This is Understanding Combine, written by Matt Neuburg. Corrections and suggestions are greatly appreciated (you can comment here). So are donations; please consider keeping me going by funding this work at http://www.paypal.me/mattneub. Or buy my books: the current (and final) editions are iOS 15 Programming Fundamentals with Swift and Programming iOS 14. Thank you!
Data Task Publisher
A URLSession data task (URLSessionDataTask), which goes out on the network to fetch a resource, is matched by a URLSession’s data task publisher (URLSession.DataTaskPublisher). If you were using a data task with a completion handler — that is, if this is not a URLSession with a delegate — you can use a data task publisher instead. You can supply a URL or a URLRequest:
func dataTaskPublisher(for: URL)
func dataTaskPublisher(for: URLRequest)
I’ll just repeat the example I developed in the previous chapter:
URLSession.shared.dataTaskPublisher(for: url)
.map {$0.data}
.replaceError(with: Data())
.compactMap { UIImage(data:$0) }
.receive(on: DispatchQueue.main)
.assign(to: \.image, on: self.iv)
Unlike a real data task, you don’t have to tell a data task publisher to resume
to get it started; it starts when you subscribe to it. And there’s no completion handler; the publisher is the completion handler, by which I mean that it doesn’t publish until the task ends.
At that point, either there is a failure, which is a URLError (for example, because the network was down, or the URL was bad), or a value is emitted, which is a tuple consisting of a data
(Data) and a response
(URLResponse). The publisher has then done its job; a failure is a .failure
completion, and a value is followed by a .finished
completion. In real life, however, a .failure
doesn’t have to be the end of the story, because a downstream operator can be a .retry
, which responds to a failure by catching the failure (so that it doesn’t get any further downstream) and resubscribing itself to its upstream publisher, thus causing the data task publisher to start all over again.