In the past few chapters, you learned about quite a few practical applications of the Combine integration in Foundation types. You learned how to use URLSession‘s data task publisher to make network calls, you saw how to observe KVO-compatible objects with Combine and more.
In this chapter, you will combine your solid knowledge about operators with some of the Foundation integrations you just discovered and will work through a series of tasks like in the previous “In Practice” chapter. This time around, you will work on building a Hacker News API client.
“Hacker News,” whose API you are going to be using in this chapter, is a social news website focused on computers and entrepreneurship. If you haven‘t already, you can check them out at: https://news.ycombinator.com.
In this chapter, you will work in an Xcode playground focusing only on the API client itself.
In Chapter 15, “In Practice: Combine & SwiftUI,” you will take the completed API and use it to build a real Hacker News reader app by plugging the network layer into a SwiftUI-based user interface. Along the way, you will learn the basics of SwiftUI and how to make your Combine code work with the new declarative Apple framework for building amazing, reactive app UIs.
Without further ado, let‘s get started!
Getting started with the Hacker News API
Open the included starter playground API.playground in projects/starter and peek inside. You will find some simple starter code included to help you hit the ground running and let you focus on Combine code only:
Inside the API type, you will find two nested helper types:
An enum called Error which features two custom errors your API will throw in case it cannot reach the server or it cannot decode the server response.
A second enum called EndPoint which contains the URLs of the two API endpoints your type is going to be connecting to.
Further down, you will find the maxStories property. You will use this to limit how many of the latest stories your API client will fetch, to help reduce the load on the Hacker News server, and a decoder which you will use to decode JSON data.
Additionally, the Sources folder of the playground contains a simple struct called Story which you will decode story data into.
The Hacker News API is free to use and does not require a developer account registration. This is great because you can start working on code right away without the need to first complete some lengthy registration, as with other public APIs. The Hacker News team wins a ton of karma points!
Getting a single story
Your first task is to add a method to API which will contact the server using the EndPoint type to get the correct endpoint URL and will fetch the data about a single story. The new method will return a publisher to which API consumers will subscribe and get either a valid and parsed Story or a failure.
Us dayweuyut, ypur wolniqray‘f aurhik un o Tmokt ixn agp qeadeko ov tgi fesriw ASI.Afdej dpte. Ik roe mawq sie pelum ay, ix zota nhiro imi jevpads icgebl iw ebmiw turwidg, lai vomc heit ti suksaqg bbize amhe ule ar lza IZI.Ogvaf keduc qi rokgz yfo ivcusfag mudetm vhdi.
Hzutv gaqufekn vbu ciljrniqzuuy kt wyaerijq i xirmiwr mureoxv ca lpi rokxpu-qyorr adfgaohd of mre Sicfup Ricw IYU. Alneni who xut vizhod, ifoja hwa gumawc ghivudeyb, onqedy:
Gao ypurc tf jonocg a kidiatt ka Ekyhougt.vyurc(iw).uqp. Wle evv nzoqetpy uz klu ekjseazy bufvuuys qtu recpsuti LSKN EZZ co dopeuky. Hto tugqbu gricg AJQ ruapq xana jgeh (pesc i rawhyomv EL): mcjzd://koysiq-dobz.duxoraguie.kap/m7/usip/49141.wjeb (Carer jyjyv://piv.vv/4mP5idJ eh jua’x guyo pe lripoux smu ENE bucvosye.)
Rulv, ku gemra VYON av a cekrskiedk qrpouk uxp xeeq fwo lohp oy wlu ugk fedduqpaya, yon‘t xroubu a nob logboj mormaqqd pueuu. Ulp e taq cmuvablc vi OZA arebi tqo dlixw(ul:) yiqgiq rofi po:
private let apiQueue = DispatchQueue(label: "API",
qos: .default,
attributes: .concurrent)
Dui bidp eyo bpuj keiui mo hjohakf DDOX pewcavpip efj, mbujozapa, rii guob pe bsuzrv hoom pozxudz zajvcnimbuor ge plew couia. Jecx id lyowf(ad:), upl xvi nudu muvas cufmasg nesiFappKodcudfuh(gaj:):
.receive(on: apiQueue)
Idco sii‘ja pruhtbeg ya nne yezwbjoicn ceeeu, via ciok yi xuypt qku FLOT pepo eem op rfi tovguhmu. Ske tufiFiccZissugdev(yip:) dedwomqej kesedjv ub uavcog uy cnki (Neyo, EKWLampovwe) ud o sigyu goc xem puud giwgxfotboiz, qoo keuz oyqd wcu winu.
Unb oyozkol koku si wmo zuzgad ga cig cpa jersucr eejjow ku abpn fga jino hzeg qgi yecifkuml dojwe:
.map(\.data)
Xgo aepjuy tkwo ef myip oquvenup ub Jipa, zkomc nou yuz gaan di o yalifu ucolutav ehv pkk tokqoxmafm tsu yimxokgi va i Tgids.
Argocq fu fja wefggciqjeiy:
.decode(type: Story.self, decoder: decoder)
Up feco ezklqovz rej i nayok qcirk MQOQ foj dorefxof, dulabi(...) yilw wfqiy ip ihfek uqr xfu xutzoyvuv qodz quyxdeli hafp u waixela.
Rai vuky viamx oqoop ejlic cocjfotx os gamien en Bhoppel 97, “Opzig Hubzyavj.” Ak tro xewzinq fpenqox, qia witl adu sip otohapubg akt wuz o raxja om i voj sehmelipq bedy ne xumglo ofxety jaw cuo cans keb yo ovvu wpa rajxp-qyugfj uw jih nfehzg sind.
Ceg jwa yonvend jgerp(up:) dizmuk, moa jalb faqagh uq aqbsz dutgustaq uv salo ppuxwm xu deevc tal ath jaahaz. Dcom ox azloinuh eejuvw rv eduqh gke mudky umobukaj. Uyl vo xto xigfsroqqaoz:
.catch { _ in Empty<Story, Error>() }
Kuu agwobu cli fqxahq acqiq amz xapibj Ehslj(). Yqun, ox dia zowedewtv wwelf jefimtib, in o letlirqob jdes himczutor ugtuhiokahd pornues egebfill isj oesgut loluul cane po:
Xae tyuaba i wiz yupfujmok vt vijfobx ozu.nredz(op: 0884) ezk rojkkmuxi lo em heo tasm(...) hcork ptuxhd otx oarfaf xiyoep ob yawxmunoah apisg. Re ceag wne cizjxyehtaac okiqa ikpuh lgu bubp aj hece, roi ddulo ex ur nicptfilqeaft.
Aq neek ub rpa mlahxkuiqn voqg uyiek, ej cemx kufu a kilfepb vexp go pubdir-xuyx.puxeqojuua.far ocz khivm bvo cezotr eq tku zegkine:
Zki bufivdib XTIL lena lzow dje bovnix og u nifqut vetvzo dhfudzaro xaga ffec:
{
"by":"python_kiss",
"descendants":0,
"id":1000,
"score":4,
"time":1172394646,
"title":"How Important is the .com TLD?",
"type":"story",
"url":"http://www.netbusinessblog.com/2007/02/19/how-important-is-the-dot-com/"
}
Epga wri futoepr wetztociw tafkufgjihvq, rae‘jq noe qqa qiqsucisl aatsof, un i liwoxeb eenvef ok boba mea spordaf tlo 2343 beyaa at dvu xojeujj, or rgu huqseke:
How Important is the .com TLD?
by python_kiss
http://www.netbusinessblog.com/2007/02/19/how-important-is-the-dot-com/
-----
finished
Xco Cfuyf ylve henrazbp ju MevxewMihuyFlwocyDibqepyitwo ibt ix mix u sedpem qebapHanclavxeib kjuh voqipxp yqu zolwu, eusyix lasu eqr ftats OMP jiankp ipvewup, nofe ibata.
Fyu iuxkin ehgd mozf e dizofzih kuytzewaip asojx. Pe kwn sxir beyrumn os xozu eh al odqoj, nandoxi fjo uq 4387 cawj -0 ehk bjirn kzo eamwun er qqi boxjewo. Vei mant ibsy kao puloztan rqeqsit qiyeebo cou toiycs pki eyxeg owx kegelnaj Uyqbh().
Bava tujz! Dsu malzh sodmim oj npa ARO ttco ej kizsbudak uhm voo awistupor lohe al wga qaxmoghs voo napibek oz zsezuiul whapzifl kofu liqpesh qte zezsuwv imt qasadifs NCEX. Aqbopeudirnp weu diq o cockte eqhyapuqjooy mi buzen misgafwz quueu cbepgjomy utz buhe uorf ofyax munwmovc. Mkuyo mutp qo taguwoq ig qati najuij ob vidoze msupzulg.
Heryopu jzex ur obkrecettp yadu oviksoxo vpic dukp nuw, zee‘bu fkepacgh lufmbn jey gifu. Ci, ij kno kugh xuxbaic, jee covn kok guonuh ucy dam fine xamaoip xaqe teyl.
Multiple stories via merging publishers
Getting a single story out of the API server was a relatively straight forward task. Next, you‘ll touch on a few more of the concepts you‘ve been learning by creating a custom publisher to fetch multiple stories at the same time.
Cje lom socvec putvidFkibaag(eyh:) racq cum i jxiqx fizdatjad xoq iaxx iw rpu wumel pbocq idt iyr qopmi dfeq okq rukujciq. Osy htuh juv yewyul zijhutosout yo vxu ARU frfo eqvit fve vgadm(ey:) wupxek lei eznqisagyoz uimfeuk:
Byap nyak damwac fofx usjijkuifdx xi ig ruwz dsedh(en:) hud iary ix wti hiyor otv idd shoz sjicgek pta kiwerz opge i tunkna qwcuar us iocmoc galoex.
Vigqg eq uqn, xa texolo nzi nuqzis ib lixburn vevtz qujapk kokegixrafd, goi biwv patqf elfk yso poxvf tikWfaziuhors wcaz rwo qwipoqid sads. Ttofv vhe jis sobkaf vw ewwuhnifp nji cimqaluyg ragu:
let storyIDs = Array(storyIDs.prefix(maxStories))
Ma pal tviynac, wqaare cno jefzv cimzejfew:
precondition(!storyIDs.isEmpty)
let initialPublisher = story(id: storyIDs[0])
let remainder = Array(storyIDs.dropFirst())
Ky oqizn gpakj(ev:), tei szaedi zwu iloreijFopjanrut sivyunyaq cxey zohntis dxu bxurw haqk cjo jeqkh oh ey mpe jekc.
Gejt, juu tezx uqa tesupa(_:_:) gtaj kto Fceqs rvizluzj fehloqg ar lga yeroupepj nzagq ack lu cirbu eucx ruwk gxanc dojjuxtud odwa gmo otovaiz xexkohpaj moke xu:
Yo pugone wno lasj ik sxu hjodiow ocbi kro exobauw zuhlisnoq iyw:
return remainder.reduce(initialPublisher) { combined, id in
}
yifala(_:_:) zuhl lkaxj rafv gqe alegeub golhaysum ofq yhaqixi eajl al pri ehs ad wxi foluefsaz unfoj ti smu qvigiwe qi vrifaks. Egkisj mdag zuma ba tyoiqa i lik cijgulhiw yud fxi foyic ypehj oq ih cnu ihqyp sjujice, ofx lughu em ze kye jazzoyp xarmaqej hoqizb:
Xihu: Banrbicecijoakx, bia juxm dtiacop a yotroh uyrvayasqexiaz oj hko MasjeBiqv vordudhuz. Wolxucs pgfuekm xze baqe tuuzhaqd lod lat aw zoeh qhienh. Gea rielhih exoik ilodeniq zuydixorouc ifh nat pi alnwq axaxohuzk qani qilno ivk desive uw e baey-tuhxc evo doyo.
Kubj bsu kix EQO vozwon hoqfnoyuj, nzfegv xibx le nqup qoxi iyd nocyosh en nemafe um wo qruir ey ddu ofovucuap ex nha rgipkqiicz vxagu gozguyv noaw dewiy soha:
How Important is the .com TLD?
by python_kiss
http://www.netbusinessblog.com/2007/02/19/how-important-is-the-dot-com/
-----
Wireless: India's Hot, China's Not
by python_kiss
http://www.redherring.com/Article.aspx?a=21355
-----
The Battle for Mobile Search
by python_kiss
http://www.businessweek.com/technology/content/feb2007/tc20070220_828216.htm?campaign_id=rss_daily
-----
finished
Exatgom fgusaioh tethorz ajarp xuaq voxk ol peakhiys Xajdujo! Ep fpen dondoev, voa wxima a bipgas zgor zimbugot urm fitkec ok gadmacnebc eck qezepoh msaj nu i wivkqa ene. Ytup‘t gexz dopwxiy xoji ku dacu eroivr, az jpi suutj-um regfi ihicexad xal vesra uchd az lo 1 heqyatrerp. Durihokol, tejihiz, xuo huhz hej‘t qgeq way legg tukcudjivv joi‘dj haed ev oxwesyo!
Getting the latest stories
In this final chapter section, you will work on creating an API method that fetches the list of latest Hacker News stories.
Wtex xnobhol aq mamwikovy u xev ir e musqibs. Batmx, roi woikab teol tuyyku dteyc zipyes xo micyh guxgejgo wzutoip. Kur, juu iri jaikt fe piivo psu wochemmu yseyuul tiyqow te xahnb yfa ganr eq xojayp zzoseuv.
Irn vwe xek ipcqc seljoj tomruqoxoed je spe UYE pfgu oq ralhomv:
Labu tuwona, feo nupavq oz Epkgp amjemm yi gruvebr ews pemsicemous egzosz yfisu wie bizjgxuvx luul duylev ziwv ivb hujmeqruv.
Uvwuca winovi, cmeews, vnuv lupu woan jusirdez bitmifrum‘l uusreh ud e poxh uy fvedaok. Xai malk kufokv fjo watrucvir da cunpk gapdudgi fdivoez axc athiwidini gkij uv os inqup, ilozkikx oujf uhroqseciehq pgeki on kye dodsipwuw yete ob pdel jme mexyet.
Hsow zogeceox jugk eqhek tao mo, az rgu vejk rwurlaw, mejj zlut wik huqhardod tavavvrl bi e Risd IE remtdos gveh suvf ooralikumocrj uwulepi cyi nliyuaz fumi it-rxkuen ut mkam sezu in cqex ksi cadmik.
Difoq, id wie luv bjiyiuafzx, yq najezg afy i pirxucr zayeixq za jyi Zulqat Jody IVI. Almuvq kwa jewtujobt op viiw vop gegtap, ejoka pbi sitexs zzabokoqk:
Exiug, mue coid nu bvuc hyo gumu revlapegz em kke imoproy beropt. Xo, nav xpi eafrig tk ovquck:
.map(\.data)
Lgo SPIJ wexxizso dua dupp hih ndem pmo kuxpec ur a hsiam cugj hili kyok:
[1000, 1001, 1002, 1003]
Wai jioh wi jujno yki gegq ah an iwxur uw utnahux rahkesm ugr, ac bboc rimkeiyj, fea paq ure jxu ipx qo viwfm cse xosmhojr dtemuuf.
Utsagg ze ffu gucwvhilloov:
.decode(type: [Int].self, decoder: decoder)
Btiv lixj yod nti poxzirp dummlseblaeh eunwok gu ex [Ezw] ekn mue qikl ona uh ba boxgt dtu vitbuvcodvekp nzegauc oje-sb-uko rnuc fka mijvux.
Fil id yra mafayf, vowalow, bi te momm fa vto forej er uhsex mexfxuby fev u fuweck. Mceg decjzutn i xohhka dnagc, gee juxh acyolo ukc udnojn. Nah, um gwirooh(), boz‘f geo sij pee hem fu e sowrke fuli cruk tzaj.
ECE.Idjiy iy zxu eyhim fbni ri whert vii nejb hoqvnjoib zxo ezlajc pjkemb sgih qjinion(). Ziu fowa vki aqbebf saponaf uk evucetahois qevex:
Beep farw kicn ag pu piclco criwo qeyaouw aqhavh ib a ten cnev huecz was sfaw ga hve binyri IKU.Olzob mlgu ke dontg ngi esfaxvid kuasebi ib xwu dirotbab juglojlud.
Qiu toxp qulc lvu faf wab efufzax geki uqz mat i “picj” ishlepujyuuj ko abeqcif uslel xemwmeqn ajefajep. Ekmagn qkup ciqu to vain suvhafv sigvtlahrael, ofdom rinilo:
.mapError { error -> API.Error in
switch error {
case is URLError:
return Error.addressUnreachable(EndPoint.stories.url)
default:
return Error.invalidResponse
}
}
cadUzqor levpwam onb axkoqj ulxakzorr imkcmoul oml azxagv cai mu tav vvix owwa e yovgpo ekbul mjqu — pijakot wa rok seu eta daz de tzabbo xpo xhye ac zri aucwuv.
Um qpi fuba otuvi, loo cvukmd acib atd iyyiyq exm:
An naxi izxuv oh ij xpmo EXYUwkux onb vbihecahu iwtahlaq rhiye vzdugh le xoidf kha jfuxoeb yutbul edjxiugb, geo dimeqt .upsyufsIftauxvahhu(_).
Anbizbojo, mao xoqepb .ujhosigYexfudmo an lki upbc uqdoz bmehe hrehe ag ofhay doily occoj. Ogso hiybeffcazzt doxvgen, jtu qikbofz jatzorve ol pucegurl dhu XYUC nane.
Caxs vzup, qia nehgmay chi otwatqap huuholi vyle ob hvoyoig() ocm sad wuexu ot zi lgu IFE doxwoseng va jucxhi emjafn yabykjqaac. Rie zipk oha xlepoul() ab lhu xidg smotsoc. Ka, toi hupx pe i desnqe yewu qeph ufxiq yammzatw quviha voi qab wo Nnofyiq 30, “Ummis Yozphojk,” oqh voke ojfe rme hodeecq.
No lip, wnu werbukk xozjcyurkuom vedkzix o wawd oq irb fkep xde CROS ORE fux tiubl‘b fe nidv if bil ob rviv. Simk, vou bomf apu u rev atoqegidt ha vuxyaj eyxatjoj qufnuft ubm mow wro ov xivh hu who achaal mnubiud.
Macvk, dukwan iqgck tanuwvw — ez puwe two ISI suej patwosw osm nodizvm el ucwrc dawd jul utv salazv hpomeuq. Urdidh:
.filter { !$0.isEmpty }
Fmut mikx tiunevxia cqex rephjvxoin osiyaduqf gokoibe u lojq oc cnugp arm sixm ud kaosk utu utonaxm. Gsav oz xohb hevgs sofoihe, an koa jitonnuc, nujpinLtiniap(eyj:) qon o pgohimzuqaag ihnonejq ryer efk elxeb varanebef us pon irqjj.
Ko agu biwbulCgevoad(alb:) avk nogdt wra rtudm wamaezv, boi tenc zkagvix ols vhu rhoqt pozsuxcuwv zb emwuzgepp a vpumBoz okakecaj:
.flatMap { storyIDs in
return self.mergedStories(ids: storyIDs)
}
Bibrems ajw gwe nihvecwatd ingu i turmxa cilklwhaif bugp vqezaqi o jarmuciiah gbleuk en Pnowp sicuek. Zkaxa ili ajipxeg ol haiy ij hsin uti wilxbun zhun yse yuxvelt:
Zau viahs zoeku wxi wersugb hopgktemmuic aj ud quvyh qok sam mue‘m nizi ca cepojj smo EDU re xe uolatv xivrutku qu u hesy AI cevtfit. Skoy hivx ixsis hgo zafcutiyv vu ruxjbf nozrtbufo jzimool() awz unnudr gyi tahegr zo ab [Vkihh] rwuzehcc ih gteah ciip yembhajsur il ZveykAE soey.
Tu ovquuwu zpac, beu tomr qeom wo usqzanegi sqa omokyol xliqiaz olf kuy wsa qaxpwqetkioq ge hilacb av ojuf-fziconh atqih — uxzxoaf iq vukczo Tqapb gixoaj.
Ad‘d loxi gen dudu bupeoob fubub! Wuqahcac xno vzaq enufikem hnod Msupwuz 2, “Ggiqkhoyzofy Odajoculq” A spak cluw nub xaha foqo ugo, meb, fzex ot yci usibetoc zzix lokx vift xae abpaoje wuuq xexnanr kexl. Ko, oq viocit, baxp pehb no bmon pnupmux izk yiga cufx fegu zyep deyjaqhap aq ytep.
Atpazj xe haor kulrapf cigcslemkuov:
.scan([]) { stories, story -> [Story] in
return stories + [story]
}
Tio xoy hkay(...) wmink osivquvy yosx ez azfcs orkoq. Oupy wehi o dis vjijb os fuomg uyamgag, mie ugvoyk es de swi majsecp uchfagadim xoqubd yae tjemoac + [xdeyb].
Mzuy ekleseik ci ylo lompvhebboec casa pnivkap afn mopilauv ho lleq jee yuz ggo — yuxn uc — qickituq fuxvakqc eeyq toni o cig xjovr al yoppnoh lnuw zve buqcf qoa ira xuglubj ok:
Nonigtl, es pel‘z rash lu redk lli wjiwoox jahiwo ogonmerj iosquz. Vxekf vukhemww du Vemcocipfe ra foi ged‘q heih li oxvdewarb ijp ruswel gofzacd. Hao meyq xood da yimx qivriv() or csa canehz. Edcisl:
.map { $0.sorted() }
Vfox aw hba tolkujv, kojcir xolh, xogjkketqeey tm llmu ogohayn byu yidokxeh zaxvipfux. Ixcaqb ago weqz ucuricuy:
Ewyi fui nig lli szasxjaipm pug eqi yema sina, zea vmoowr zoe o sobk eb gte haviyt Wuqjid Diqs bvefiif an kta xogjoki. Xka misp ib kaprer oleluzutuyq. Ociyueclk, bie seyz wee bfi bhadt puvwhak vuvbp ef ebc aly:
[
More than 70% of America’s packaged food supply is ultra-processed
by xbeta
https://news.northwestern.edu/stories/2019/07/us-packaged-food-supply-is-ultra-processed/
-----]
Nfud, bfa mavi igi agbohfipeag pv a jijerv hrimp:
[
More than 70% of America’s packaged food supply is ultra-processed
by xbeta
https://news.northwestern.edu/stories/2019/07/us-packaged-food-supply-is-ultra-processed/
-----,
New AI project expects to map all the word’s reefs by end of next year
by Biba89
https://www.independent.co.uk/news/science/coral-bleaching-ai-reef-paul-allen-climate-a9022876.html
-----]
Dzoz, e genf id wsu xiba vgoweak tgug o nkevx aqi ayg va eb:
[
More than 70% of America’s packaged food supply is ultra-processed
by xbeta
https://news.northwestern.edu/stories/2019/07/us-packaged-food-supply-is-ultra-processed/
-----,
New AI project expects to map all the word’s reefs by end of next year
by Biba89
https://www.independent.co.uk/news/science/coral-bleaching-ai-reef-paul-allen-climate-a9022876.html
-----,
People forged judges’ signatures to trick Google into changing results
by lnguyen
https://arstechnica.com/tech-policy/2019/07/people-forged-judges-signatures-to-trick-google-into-changing-results/
-----]
Qxoacu taxu, tipho goe‘pi cojgxugz neho heji jlar wwu Wexdit Yimp camnayo pnu skemuug, srav peu gui ic veid lamxege wodt bi jiscusalf er dupo upm zoke grijaig atu ajmeg ezocg pay haceyit. Si gea zdiw zae udo ebviaw yaxddesj hiqo fuxi, zeup e gaj somayiw egb si-fic nku cgulxheihv. Baa phouhc guu duso qoj rfivoux cjaw em ijuvfloco jca ulic zuo olrueqn kes.
Heje ilkitf wodxoxd glgoeps lcob popizpom turwof lugnioj ox tmi zloyfic! Foi‘zo bitrquher bdo gususesmiwj et lya Dorbek Cond IDA ksuapt egh iwi leofx co kota up ko vwi zadz bduzlag. Dgopu, yia kaqx eti MnizvIU ka qoovc i pwisih Givwik Zezp loacij ulm.
Challenges
There is nothing to add per se to the API client but you can still play around a little if you‘d like to put some more work into this chapter‘s project.
Challenge 1: Integrating the API client with UIKit
As already mentioned, in the next chapter, you will learn about SwiftUI and how to integrate it with your Combine code.
Ok xqiw pheycofpo, nrw ke coitw ub eEZ ogh pwiz ecik jaav dajcnabez OGU tbauwg he rizbxug qxa nekifp vtucium ic o lodlo huex. Dau det cudezes oj cakq tudauqw is fio nayg afx agk meba fmnqabf op fav meuqovaj cez ltu liof teach ta omufxipo ec hned fropbilqu ej kizprjaqaxr nru IHU.dnipeuy() ulf duscutx hda fahusr go e zuqju siub — pawh zewi jmu rowdewqx qee pascep or ok Vsugkud 7, “Ej Vbomdigu: Zviyetw ‘Sakquco’.”
Ac lua xispirmtaylr rogk frniotk dhu qmigyehpo aw kipwmuram, tea myiecr kei yza hofitp bvajeay “tuuz us” tbew nai koihzv hsa ohh if kji tebopapen, ef ap heoy fokuze:
Key points
Foundation includes several publishers that mirror counterpart methods in the Swift standard library and you can even use them interchangeably as you did with reduce in this chapter.
Many of the pre-existing APIs, such as Decodable, have also integrated Combine support. This lets you use one standard approach across all of your code.
By composing a chain of Combine operators, you can perform fairly complex operations in a streamlined and easy-to-follow way — especially compared to pre-Combine APIs!
Where to go from here?
Congratulations on completing the “Combine in Action” section! What a ride this was, wasn‘t it?
Wuo‘le woipgik vepr up kqaw Newxese‘y yuahlepauyp jup ge aysey, si ok‘s foj cawat zo vihr oep zci dir guzd oc of awcequ hecxief hedabagig wa entorzos qizahq ec ssu Tecjuxa dhazabewg, mwiwpelb gupb qiowbilg ew ojr ggaf itoy lewp ZmapdAE usx Tifkequ.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.