---------------------------- --------------------------
| 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 aFinalizedSignalProducer
instead. -
Repurposes
start
to 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 theEvent
enum 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.