Skip to content

Instantly share code, notes, and snippets.

@js
Created January 25, 2017 20:06
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 js/5a516867c24600081e8883550ad527bd to your computer and use it in GitHub Desktop.
Save js/5a516867c24600081e8883550ad527bd to your computer and use it in GitHub Desktop.
//: Playground - noun: a place where people can play
import UIKit
struct Person {
var name = Observable("Bob")
}
enum Event<T> {
case next(T)
case error(Error)
case completed
}
final class Observable<T> {
var value: T {
didSet {
subscribers.forEach { $0(.next(value)) }
}
}
private var subscribers: [(Event<T>) -> Void] = []
init(_ value: T) {
self.value = value
}
deinit {
subscribers.forEach { $0(.completed) }
}
func subscribe(observer: @escaping (Event<T>) -> Void) {
subscribers.append(observer)
}
}
var person: Person? = Person()
person?.name.subscribe { event in
switch event {
case .next(let name):
print("new name is \(name)")
case .error(let error):
print("signal error: \(error)")
case .completed:
print("signal completed")
}
}
print(person!.name.value)
person?.name.value = "John"
person = nil
print("---")
final class AnyObservable<T> {
let handler: (@escaping (Event<T>) -> Void) -> Void
init(handler: @escaping (@escaping (Event<T>) -> Void) -> Void) {
self.handler = handler
}
func subscribe(observer: @escaping (Event<T>) -> Void) {
handler(observer)
}
func map<U>(_ transform: @escaping (T) -> U) -> AnyObservable<U> {
return AnyObservable<U> { observer in
self.subscribe { event in
switch event {
case .next(let value):
observer(.next(transform(value)))
case .error(let error):
observer(.error(error))
case .completed:
observer(.completed)
}
}
}
}
}
let obs = AnyObservable<String> { observer in
observer(.next("Hello"))
observer(.next("World"))
observer(.completed)
}
obs.subscribe { event in
switch event {
case .next(let value):
print(".next: \(value)")
case .error(let error):
print(".error: \(error)")
case .completed:
print(".completed")
}
}
obs.map({ str in
return str.characters.count
}).subscribe { event in
switch event {
case .next(let value):
print(".next: \(value)")
case .error(let error):
print(".error: \(error)")
case .completed:
print(".completed")
}
}
//Bob
//new name is John
//signal completed
// ---
// .next: Hello
//.next: World
//.completed
//.next: 5
//.next: 5
//.completed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment