Created
January 12, 2020 18:02
-
-
Save madcato/8b392c63d6c15f5b8a117a589e2d0f35 to your computer and use it in GitHub Desktop.
Observer sample class using @propertyWrapper and class extension
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Observer.swift | |
// TestAspect | |
// | |
// Created by Daniel Vela on 12/01/2020. | |
// Copyright © 2020 veladan. All rights reserved. | |
// | |
protocol Observer { | |
associatedtype Value | |
func update(value: Value) | |
} | |
class AnyObserver<Value>: Observer { | |
private let updateClosure: (Value) -> Void | |
init<ObserverType: Observer>(with observer: ObserverType) where ObserverType.Value == Value { | |
self.updateClosure = observer.update | |
} | |
func update(value: Value) { | |
self.updateClosure(value) | |
} | |
} | |
extension Observer { | |
func toAnyObserver() -> AnyObserver<Value> { | |
return AnyObserver<Value>(with: self) | |
} | |
} | |
protocol Subject { | |
associatedtype Value | |
mutating func add(observer: AnyObserver<Value>) | |
mutating func remove(observer: AnyObserver<Value>) | |
func fireNotification() | |
} | |
class UserView { | |
func render(user: User) { | |
print("User is now: \(user)") | |
} | |
} | |
extension UserView: Observer { | |
func update(value: User) { | |
self.render(user: value) | |
} | |
} | |
@propertyWrapper | |
struct Observed<Value>: Subject { | |
init(initialValue: Value) { | |
self.value = initialValue | |
} | |
var value: Value { | |
didSet { | |
self.fireNotification() | |
} | |
} | |
var observers = [AnyObserver<Value>]() | |
mutating func add(observer: AnyObserver<Value>) { | |
self.observers.append(observer) | |
} | |
mutating func remove(observer: AnyObserver<Value>) { | |
self.observers.removeAll { $0 === observer } | |
} | |
func fireNotification() { | |
self.observers.forEach { $0.update(value: self.value) } | |
} | |
} | |
struct SampleClass { | |
@Observed | |
var user = User() | |
mutating func run() { | |
let userView = UserView() | |
$user.add(observer: userView.toAnyObserver()) | |
user.name = "Phoenix" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment