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?
CodePudding user response:
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)
}