Skip to content

Instantly share code, notes, and snippets.

@kristofk
Last active August 17, 2019 10:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kristofk/317c86858e049f2d6fa98b1cc97e494c to your computer and use it in GitHub Desktop.
Save kristofk/317c86858e049f2d6fa98b1cc97e494c to your computer and use it in GitHub Desktop.
Observer Pattern in Swift - Or at least my custom implementation
class Person {
var name = Observable("John")
}
var person: Person? = Person()
var subscription: Subscription<String>? = person?.name.subscribe() { (oldValue, newValue) in
print("name changed: \(oldValue) to \(newValue)")
}
person?.name.value = "Jane"
person?.name.unsubscribe(subscription!)
subscription = nil
person = nil
struct Observable<T> {
typealias ChangeHandler = (_ oldValue: T, _ newValue: T) -> Void
var value: T {
didSet {
notifySubscribers(oldValue: oldValue, newValue: value)
}
}
internal init(_ value: T) {
self.value = value
}
private var subscriptions = [Subscription<T>]()
internal mutating func subscribe(changeHandler: @escaping ChangeHandler) -> Subscription<T> {
let subscription = Subscription(changeHandler: changeHandler)
self.subscriptions.append(subscription)
return subscription
}
internal mutating func unsubscribe(_ subscription: Subscription<T>) {
self.subscriptions = self.subscriptions.filter { $0 !== subscription }
}
private func notifySubscribers(oldValue: T, newValue: T) {
for subscription in subscriptions {
subscription.changeHandler(oldValue, newValue)
}
}
}
class Subscription<T> {
typealias ChangeHandler = (_ oldValue: T, _ newValue: T) -> Void
let changeHandler: ChangeHandler
init(changeHandler: @escaping ChangeHandler) {
self.changeHandler = changeHandler
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment