Last active
October 3, 2017 12:59
-
-
Save TiagoBras/89e92b1ebe686e1fbe1c2fcb01c77e26 to your computer and use it in GitHub Desktop.
Observable in SWIFT
This file contains hidden or 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
| import Foundation | |
| class Observable<T: Equatable> { | |
| typealias HandlerID = UUID | |
| struct Observer { | |
| typealias Handler = (T) -> () | |
| let id: HandlerID | |
| let handler: Handler | |
| } | |
| var state: T { | |
| didSet { | |
| if oldValue != state { | |
| observers.forEach({ $0.handler(state) }) // Notify all | |
| } | |
| } | |
| } | |
| private lazy var observers: [Observer] = [] | |
| init(initialState: T) { | |
| self.state = initialState | |
| } | |
| func subscribe(_ handler: @escaping Observer.Handler) -> HandlerID { | |
| // This is just here in the remote chance of having two handlers with the same ID | |
| while true { | |
| let id = HandlerID() | |
| if observers.contains(where: { $0.id == id }) { | |
| continue | |
| } else { | |
| observers.append(Observer(id: id, handler: handler)) | |
| return id | |
| } | |
| } | |
| } | |
| func unsubscribe(handlerID: HandlerID) { | |
| guard let index = observers.index(where: { $0.id == handlerID }) else { return } | |
| observers.remove(at: index) | |
| } | |
| func detachAll() { | |
| observers.removeAll() | |
| } | |
| } | |
| // Usage | |
| class AppSettings { | |
| private var showHeader = false { | |
| didSet { | |
| showHeaderObservable.state = showHeader | |
| } | |
| } | |
| lazy var showHeaderObservable = Observable<Bool>(initialState: self.showHeader) | |
| func setShowHeader(_ flag: Bool) { | |
| showHeader = flag | |
| } | |
| static let shared = AppSettings() | |
| } | |
| let handlerId = AppSettings.shared.showHeaderObservable.subscribe { (showHeader) in | |
| print("Show Header: \(showHeader)") | |
| } | |
| // Prints 'Show Header: true' | |
| AppSettings.shared.setShowHeader(true) | |
| AppSettings.shared.showHeaderObservable.unsubscribe(handlerID: handlerId) | |
| // Prints nothing | |
| AppSettings.shared.setShowHeader(true) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment