Skip to content

Instantly share code, notes, and snippets.

@TiagoBras
Last active October 3, 2017 12:59
Show Gist options
  • Select an option

  • Save TiagoBras/89e92b1ebe686e1fbe1c2fcb01c77e26 to your computer and use it in GitHub Desktop.

Select an option

Save TiagoBras/89e92b1ebe686e1fbe1c2fcb01c77e26 to your computer and use it in GitHub Desktop.
Observable in SWIFT
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