---------------------------- --------------------------
| SignalProducerObservable | ← | SignalProducerProtocol |
---------------------------- --------------------------
↑ ↑
--------------------------- ------------------
| FinalizedSignalProducer | | SignalProducer |
--------------------------- ------------------
SignalProducerObservable describes a producer that is observable for events. All the observation APIs and starting APIs are available in this protocol.
SignalProducerProtocol inherits SignalProducerObservable, and provides compositional operators.
// The intention to start a producer must be explicitly stated.
property.producer.observeValues { print("\($0)") }.start()
// Bonus: Xcode can indent this properly!
property.producer
.observeValues { print("\($0)") }
.start()
// Bonus: Xcode can indent this properly too!
property.producer
.observeValues {
print("New value: \($0)")
}
.observeCompletion {
print("Completed!")
}
.start()
// WARNING: Unused result.
property.producer
.observeValues { print("New value: \($0)") }
// ERROR: `FinalizedSignalProducer` does not have a method named `map`.
property.producer
.observeValues { print("New value: \($0)") }
.map { "\($0)" }
🎉 🎉 🎉
-
Replaces
SignalProducerProtocol.start(_:)andSignalProducerProtocol.startWith*withSignalProducerObservable.observe*, and they no longer starts the producer in place. They return aFinalizedSignalProducerinstead. -
Repurposes
startto express the intention to start a producer. (i.e. no longer takes any observers or actions) -
Renames
(Next|Result|Failed|Completed|Interruption)to(Values|Results|Failure|Completion|Interrupted). (Note that theEventenum cases need not be changed.)
Whenever a observe* method is called on a producer, it would always return a finalised producer. The difference from a non-finalised one is the inability of further composition, as FinalizedSignalProducer conforms to only SignalProducerObservable. However, the SignalProducerObservable.observe* calls are allowed to be chained, since they are all lazily attached to the produced signal.
Injecting side effects should use the on operator instead.
It was attempted in an early prototype. But then tests show that the observers would be dropped if the compositional operators and the lazy observations are interleaved, except for those registered right before calling start.
An approach of type erasing observers was tried. But it spoiled the SignalProducer constructing/composing APIs, and is prone to error if the implementor of an operator does not call the appropriate initializer dedicated to producer operators.
Using SignalProducer(on:) should be feasible, but it is relatively heavyweight.