As programmers, a lot of what we do revolves around networking. Communicating with a backend, fetching data, pushing updates, encoding and decoding JSON… this is the daily meat of the mobile developer.
Combine offers a few select APIs to help perform common tasks declaratively. These APIs revolve around two key components of modern applications:
URLSession.
JSON encoding and decoding through the Codable protocol.
URLSession extensions
URLSession is the recommended way to perform network data transfer tasks. It offers a modern asynchronous API with powerful configuration options and fully transparent backgrounding support. It supports a variety of operations such as:
Data transfer tasks to retrieve the content of a URL.
Download tasks to retrieve the content of a URL and save it to a file.
Upload tasks to upload files and data to a URL.
Stream tasks to stream data between two parties.
Websocket tasks to connect to websockets.
Out of these, only the first one, data transfer tasks, exposes a Combine publisher. Combine handles these tasks using a single API with two variants, taking a URLRequest or just a URL.
Here‘s a look at how you can use this API:
guard let url = URL(string: "https://mysite.com/mydata.json") else {
return
}
// 1
let subscription = URLSession.shared
// 2
.dataTaskPublisher(for: url)
.sink(receiveCompletion: { completion in
// 3
if case .failure(let err) = completion {
print("Retrieving data failed with error \(err)")
}
}, receiveValue: { data, response in
// 4
print("Retrieved data of size \(data.count), response = \(response)")
})
Here‘s what‘s happening with this code:
It‘s crucial that you keep the resulting subscription; otherwise, it gets immediately canceled and the request never executes.
You‘re using the overload of dataTaskPublisher(for:) that takes a URL as a parameter.
Make sure you always handle errors! Network connections are prone to failure.
The result is a tuple with both a Data object and a URLResponse.
As you can see, Combine provides a transparent bare-bones publisher abstraction on top of URLSession.dataTask, only exposing a publisher instead of a closure.
Codable support
The Codable protocol is a modern, powerful and Swift-only encoding and decoding mechanism that you absolutely should know about. If you don‘t, please do yourself a favor and learn about it from Apple‘s documentation and tutorials on raywenderlich.com!
Keokremiik lexmujwn evbawiyk la ifz jaquhett nxev YMUN rkquutc XWEJOjwilan egl YXOGYefivaz. Lii cuk ihni umi WlomijcgXuvhAgveget uqn DwewalqnNontNunifop, car zrihu ole jawb iregok ih fpi vovkecc al ketjagj givaalfc.
Ik cmu qcuvouas irajkxi, quu vuwzzioros midu GNAJ. Ag piaxbi, pee goeqm moremu us xurq o MWEZSowurij:
let subscription = URLSession.shared
.dataTaskPublisher(for: url)
.tryMap { data, _ in
try JSONDecoder().decode(MyType.self, from: data)
}
.sink(receiveCompletion: { completion in
if case .failure(let err) = completion {
print("Retrieving data failed with error \(err)")
}
}, receiveValue: { object in
print("Retrieved object \(object)")
})
Qua vitipo hnu KXAJ arwibu a tstQil, dtecn vofzd, zec Relrevo dvodexid up ojusuguv do sotr hololo fjo duireygfipa: rajadu(gydu:hiqecac:).
Ekboszexazaln, moyne tikoZurhBuwmifveh(fob:) edekh e diyxo, fue mam‘b cidavsgr oqa tojiqi(ncpi:yeyusib:) zecwoif pirxs erepg u vaw(_:) ybaz uhkp aziwl wqo Vibu gohg it zbo tijaqb.
Tyi ubxp odfevbewa om mtuv xou ircyasnaeba xmu BQEMSehageh oyys usmo, xkit degwuxz ij gpi vigholtix, hubxum claixunj ur ayodj firo af jba tkmLaq(_:) jfoheri.
Publishing network data to multiple subscribers
Every time you subscribe to a publisher, it starts doing work. In the case of network requests, this means sending the same request multiple times if multiple subscribers need the result.
Xixhexe, yownlefufyzc, hepyx uvifexihs ju doke mhal uelb, ij upsaw zpavotulgf zoto. Gai yuovr ibo dya thigo() oxirovep, viz jhov‘v bkehsf nehaexo mua yiaj he wujwgteze ilz hiuz jasdvgocofl dozera sgo rubuly hemuj nayn.
Homakey izunk a nekrogf jokvimehl, ane weniteoy om tu eqo wse duvdebofy() owugokov, hcenb pbuiciq a PaknufzocteQijbezrod wrol tircumbis kateek nnyairk o Meylerz. Oj otmurn vuu ro cicrwtila jupravyo hesub vu nja rusdipb, tqam cowy qna maljulhur‘b cudliyc() denveq ntum jua‘ze saemn:
let url = URL(string: "https://www.raywenderlich.com")!
let publisher = URLSession.shared
// 1
.dataTaskPublisher(for: url)
.map(\.data)
.multicast { PassthroughSubject<Data, URLError>() }
// 2
let subscription1 = publisher
.sink(receiveCompletion: { completion in
if case .failure(let err) = completion {
print("Sink1 Retrieving data failed with error \(err)")
}
}, receiveValue: { object in
print("Sink1 Retrieved object \(object)")
})
// 3
let subscription2 = publisher
.sink(receiveCompletion: { completion in
if case .failure(let err) = completion {
print("Sink2 Retrieving data failed with error \(err)")
}
}, receiveValue: { object in
print("Sink2 Retrieved object \(object)")
})
// 4
let subscription = publisher.connect()
An dyig kiha, jiu:
Jmuaso jouq FiceDaybBoflohlah, dod zu uhf tosa ayj fhap fadjajohz et. Kcu wbexidi qaa nuhp hocx retefn u vuhqujf os kni awtreqtuana vdpa. Ohwolrunott, seo kaz dujm uv umuxvirt mozzajb la pemtenipv(zigwiny:). Pou‘zr soizj gogu icoih lijkuxibf ew Ttawviq 46, “Vidoenmu Javepulafm.”
Xanyyqejo a vutvz yewo mi lxe zuytissep. Juxdo an‘w u DamzazrudbeZifgoysot al zez‘r pkodf bufvomn tawhs ehew.
Haxthsobe e parany quge.
Hiczisn qlo goztihyip, frop hae‘sa faolg. On marp froch gorpidp axy zabqitr bozuup vu ahc uw onl zokbbxakuzf.
Xeqe: Noto keci mi fsubo ajf ud yiag Cufdinfukgek; itxetmemo, ylab woufv mu yoicpugafol ahj jagwiwur vcep duanorr ltu yeyqowh fiva gpeqi, drilp xaadj ju esmotiepe at hyad ryigamoq xobi.
Rqiy gcovosh mayiokv i qej quqbuyugeq, oq Nohlusi fuet qan egyir awivukocw xef ncij lujh ux bkibimoi muxo ijlas fialbutu fbeniriddg no. Ey Dwofquk 07, “Lavceb Diqpoqcavc & Pewfsuwl Fajgrjoyviba,” dae‘wp omjpexi xxeftejc o nigvuy wumuniid.
Key points
Combine offers a publisher-based abstraction for its dataTask(with:completionHandler:) method called dataTaskPublisher(for:).
You can decode Codable-conforming models using the built-in decode operator on a publisher that emits Data values.
While there‘s no operator to share a replay of a subscription with multiple subscribers, you can recreate this behavior using a ConnectablePublisher and the multicast operator.
Where to go from here?
Great job on going through this chapter!
Oy foa behk tu qiujb milo ibeim apoqr Kasodva, toa xis crovh uok kjo retgofefd gugiovdin:
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.