Skip to content

Instantly share code, notes, and snippets.

@bdsaglam
Created December 20, 2019 08:46
Show Gist options
  • Select an option

  • Save bdsaglam/84d7e2e4779e9f26b5f507c538881a3b to your computer and use it in GitHub Desktop.

Select an option

Save bdsaglam/84d7e2e4779e9f26b5f507c538881a3b to your computer and use it in GitHub Desktop.
LiveData in Swift
import Foundation
/**
viewModel.message.observe(owner: self, Observer { (message: String)->() in
DispatchQueue.main.async {
self.label.text = message
}
DispatchQueue.main.asyncAfter(deadline: .now() + DispatchTimeInterval.seconds(1)) {
self.label.text = "tick: \(self.viewModel.ticker.value)"
}
})
*/
public class LiveData<Item> {
private var observations:[Observation<Item>] = []
var value:Item {
didSet {
var deadIndices:[Int] = []
for (i, observation) in observations.enumerated() {
if observation.owner.object != nil {
observation.observer.notify(value)
} else {
deadIndices.append(i)
}
}
// sort indices in descending order to be able
// to remove elements consecutively from array
deadIndices.sort { $0 > $1}
for index in deadIndices {
observations.remove(at: index)
}
}
}
init(initialValue:Item) {
value = initialValue
}
func observe(owner: AnyObject, _ observer:Observer<Item>){
let observation = Observation(owner: owner, observer: observer)
observations.append(observation)
}
}
public final class Observer<Item>{
typealias Closure = (Item) -> ()
private let closure:Closure
init(_ closure:@escaping Closure) {
self.closure = closure
}
func notify(_ item:Item){
self.closure(item)
}
}
private final class Observation<Item> {
let owner: WeakRef<AnyObject>
let observer: Observer<Item>
init(owner:AnyObject, observer:Observer<Item>){
self.owner = WeakRef(owner)
self.observer = observer
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment