Skip to content

Instantly share code, notes, and snippets.

@storoj
Created September 14, 2018 10:25
Show Gist options
  • Save storoj/ca84f692f1669a596e92e37c08eb1d32 to your computer and use it in GitHub Desktop.
Save storoj/ca84f692f1669a596e92e37c08eb1d32 to your computer and use it in GitHub Desktop.
import Foundation
let nc = NotificationCenter()
extension Notification.Name {
public static let ObservableDidChange = NSNotification.Name("ObservableDidChange")
}
let ObservableNewValueUserInfoKey = "new"
let ObservableOldValueUserInfoKey = "old"
public class Observable<T> {
public init(_ value: T) {
self.value = value
}
public var value: T {
didSet {
let userInfo = [
ObservableOldValueUserInfoKey: oldValue,
ObservableNewValueUserInfoKey: value
]
nc.post(name: .ObservableDidChange, object: self, userInfo: userInfo)
}
}
public func observe(_ closure: @escaping (_ old: T, _ new: T) -> Void) -> Observer<T> {
return Observer(observable: self, closure: closure)
}
}
public class Observer<T> {
let observable: Observable<T>
let nco: NSObjectProtocol
deinit {
detach()
}
init (observable: Observable<T>, closure: @escaping (_ old: T, _ new: T) -> Void) {
self.observable = observable
nco = nc.addObserver(forName: .ObservableDidChange, object: observable, queue: nil) { note in
guard let userInfo = note.userInfo,
let oldValue = userInfo[ObservableOldValueUserInfoKey] as? T,
let newValue = userInfo[ObservableNewValueUserInfoKey] as? T
else {
return
}
closure(oldValue, newValue)
}
}
func detach() {
nc.removeObserver(nco)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment