ReactiveProperty specification
This is the engineering specification for the ReactiveProperty
concrete type.
Overview
ReactiveProperty
defines an interface for the storage of a generic T value and observation of
changes made to it.
Reactive properties can represent existing information. Such properties will write changes to the existing information when the property’s value changes and before notifying observers.
How to create a property
let property = ReactiveProperty(initialValue: 10)
How to change a property’s value
property.value = 100
Observing changes to a property’s value
let subscription = property.subscribe { value in
print(value)
}
MVP
Expose a concrete ReactiveProperty API
public final class ReactiveProperty<T> {
}
Expose an initializer for anonymous properties
The initializer should accept an initial value. Such properties are called anonymous properties.
class ReactiveProperty<T> {
public init(initialValue: T)
}
Expose an initializer for external properties
The initializer should accept an initial value and an externalWrite.
class ReactiveProperty<T> {
public init(initialValue: T, externalWrite: (T) -> Void)
}
Expose a value API
class ReactiveProperty<T> {
public var value: T
}
Expose a subscribe API
Expose a MotionObserver-shaped subscribe API that accepts a next function.
class ReactiveProperty {
public func subscribe(next: (T) -> Void) -> Subscription
}
Store a private list of MotionObserver instances
class ReactiveProperty {
private var observers: [MotionObserver<T>] = []
}
Subscribe adds an observer to a list of observers
class ReactiveProperty {
func subscribe(next: (T) -> Void) -> Subscription {
let observer = MotionObserver(next: next)
observers.append(observer)
...
}
}
Subscribe invokes the observer’s next function with the current value
class ReactiveProperty {
func subscribe(next: (T) -> Void) -> Subscription {
...
observer.next(value)
}
}
Changes to value should propagate to all observers
First invoke the externalWrite function and then inform observers of the new value.
class ReactiveProperty {
public var value: T {
didSet {
_externalWrite?(newValue)
for observer in observers {
observer.next(newValue)
}
}
}
}
Should be convertible to a MotionObservable
ReactiveProperties
should be convertible to a MotionObservable type.
class ReactiveProperty {
public func asStream() -> MotionObservable<T>
}