Skip to content

Instantly share code, notes, and snippets.

@madcato
Created March 15, 2018 14:51
Show Gist options
  • Save madcato/e917f2619f5529b46d564c2861d4f39a to your computer and use it in GitHub Desktop.
Save madcato/e917f2619f5529b46d564c2861d4f39a to your computer and use it in GitHub Desktop.
Just another Observable implementation
//
// Observable.swift
// TestObservable
//
// Created by Daniel Vela on 13/03/2018.
// Copyright © 2018 veladan. All rights reserved.
//
//
// https://colindrake.me/post/an-observable-pattern-implementation-in-swift/
//
protocol ObservableProtocol {
associatedtype T
var value: T { get set }
func subscribe(observer: AnyObject,
block: (_ newValue: T, _ oldValue: T) -> ())
func unsubscribe(observer: AnyObject)
}
/*!
Observable class pattern
Sample implementation:
class ConcreteImplementation2 {
func run() {
let initial = 3
var v = initial
let obs = Observable(initial)
obs.subscribe(self) { (newValue, oldValue) in
print("Object updated!")
v = newValue
}
obs.onChange { (newValue, oldValue) in
print("Object changed!")
}
obs.value = 4 // Trigger update.
print(v) // 4!
}
}
*/
class Observable<T> {
typealias ObserverBlock = (_ newValue: T, _ oldValue: T) -> ()
typealias ObserversEntry = (observer: AnyObject, block: ObserverBlock)
var value: T {
didSet {
observers.forEach { (entry) in
let (_, block) = entry
block(value, oldValue)
}
}
}
var observers: [ObserversEntry] = []
init(_ value: T) {
self.value = value
}
/// If you use this method, object can't be unsubscribed
func onChange(block: @escaping ObserverBlock) {
subscribe(Observable<Int>(0), block: block)
}
func subscribe(_ observer: AnyObject, block: @escaping ObserverBlock) {
let entry: ObserversEntry = (observer: observer, block: block)
observers.append(entry)
}
func unsubscribe(_ observer: AnyObject) {
observers = observers.filter { entry in
let (owner, _) = entry
return owner !== observer
}
}
static func <<<T>(_ this: Observable<T>, _ value: T) {
this.value = value
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment