For example, I want to send a request in my viewModel, if the viewModel is dealloc. The request signal should send interrupt event.
This is my code
func request() -> SignalProducer<Data, Error> {
let request: SignalProducer<Data, Error> = ..... (This signal is from another module)
return request.take(duringLifetimeOf: self)
}
This code will send a completed event instead of an interrupt event when self is dealloc. Because take(duringLifetimeOf:)
API said:
Forward events from
self
untilobject
deinitializes, at which point the returned producer will complete.
If I am the caller of this request(). I want to know whether my request is done. If the request is canceled due to the "self" being dealloc . Then I will get a completed event. This is not reasonable.
Is my thought right about mapping the completed event to the interrupt event?
What to do if my thought is right?
I've found that caring about the distinction between completed
and interrupted
events is often an anti-pattern, and there may be a better way to do what you are trying to do if you can share how exactly you're consuming the request()
function.
That said, here's a little custom operator that I think will do what you are trying to do:
extension SignalProducer {
func interrupt(after lifetime: Lifetime) -> SignalProducer<Value, Error> {
return SignalProducer<Value, Error> { observer, innerLifetime in
innerLifetime += self.start(observer)
innerLifetime += lifetime.observeEnded(observer.sendInterrupted)
}
}
}
Then you can do this instead of using take(duringLifetimeOf:)
:
func request() -> SignalProducer<Data, Error> {
let request: SignalProducer<Data, Error> = ..... (This signal is from another module)
return request.interrupt(after: self.reactive.lifetime)
}