Skip to content

Instantly share code, notes, and snippets.

@madcato
Created January 12, 2020 18:02
Show Gist options
  • Save madcato/8b392c63d6c15f5b8a117a589e2d0f35 to your computer and use it in GitHub Desktop.
Save madcato/8b392c63d6c15f5b8a117a589e2d0f35 to your computer and use it in GitHub Desktop.
Observer sample class using @propertyWrapper and class extension
//
// 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