Here is my pipeline:
URLSession.shared
.dataTaskPublisher(for: urlRequest)
.map { $0.data }
.mapError { ...... }
.eraseToAnyPublisher()
.decode(type: MyObject.self, decoder: JSONDecoder())
.receive(on: RunLoop.main)
.catch { [weak self] error -> Just<MyObject> in
guard let self = self else { return Just(emptyPayload) }
self.hasError = true
return Just(emptyPayload)
}
.sink(
receiveCompletion: { [weak self] _ in
print("i'm here")
},
receiveValue: { [weak self] value in
print("value")
}
)
Why is sink never called?
dataTaskPublisher(for: urlRequest)
will send values asynchronously. When program execution leaves your current scope, there are no more references to your pipeline and ARC destroys your pipeline before the network request has completed.
Your pipeline returns a Cancellable. Either assign that Cancellable directly to an instance variable or add the store(in:)
operator to your pipeline.
Also worth mentioning is that if you mess around with Combine pipelines in an Xcode playground, your pipelines may live longer than you'd expect because the Playground tries to be smart about holding on to references for the sake of making experimentation easier. See this answer for an async example you can run in a playground, even though it applies neither of the fixes I mentioned.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With