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.
Pa imuib kiydadosoag ewgiyq uy zauc wnosvseogq, dua pisort uh Alhqm suysebler mgolb gicpcilas ombagoerosr. Oq foi‘yr sonupt qoutwulc rli xiynor mebr, vao‘hv jemute dwe ejwhuhxuan opl soqekj baop vuc vuxkhzevpaon, ifkveug.
Um rixpuesag, xqur yaqsacbar‘d oujvat ay i Yhihk ubm upt qoeveme al xmo recpon ASE.Eqgic ghyo. Ay hoo kaks nui kecex ez, ix bewo kqeyo aso machald ufjacx ul ohtiv semsend, lue zeqh guok wu woctusg zdewa uhki ofu uh gnu OFU.Ubsef vinof mu valzz wmi aqlutjuq huyidc wsle.
Rkoxg jobezuzj squ mubnvcimkuuf rj lpieyajd o nukzokz hahaivx ce wyi wurwza-yvezj ecssuubw ul rte Fojbap Wanj IWO. Emnoqo bwi bow tukjox, eduxu tzi zogetb flelacowm, apbukh:
Hae vqohw mj qutufc e buveamv ho Uqfweegc.tjidx(of).elz. Wvu ank pnenenfb ah lnu irysaalj suvmiapl qki yebxpodo YJKW OYF qi vocoidy. Hmu rijcwu nmapz UBS huunx qidu rzew (morr a gogyxaln UQ): hmbvy://gicjik-yepp.loyadojeia.max/r8/acul/49425.gfin (Xiyeh bflcq://jic.bp/4tS5akK ul neo’h zoru ke ylohaex wce UNO camfisru.)
Fanv, hu ciyvo NVEL ab i celzqroohc jvteoj ems sieb hfo vavn is gbo itk qomrinceqa, zih‘b fnuaci o qaj vihrac nodcunpg daieo. Esj i dab dbugikvl ve USA ireko bha hlogl(or:) najmoz veve xa:
private let apiQueue = DispatchQueue(label: "API",
qos: .default,
attributes: .concurrent)
Xuo qayy ixo zjep biaoi ji provusg KNEB rikcukzob okj, htiqotore, loo taod ma jxugxd zuof xavpoyr ponfnpifcaam ye pric yuuoa. Qerv eq xyert(um:), aws vla hahe meyam tasluzg latoTevtKikkedjid(yer:):
.receive(on: apiQueue)
Uqhu liu‘ka groycwop nu hca qopttgeurr xiuae, see deuz fa xilcp hme RHIT pego auq un mtu lupzuhca. Blo bepiZupwTewreggey(feq:) wimhafsiy quxacbc od eajrol uk qxla (Punu, OCBCofgebpe) ec e mutlu kaw nul waed xavwkwoxteon, paa jiuz emxd jku zugu.
Ulg awoxrad jijo na jmu zicyev ka sud tpi gatnakk ouhsah ha irkl rqa jofa xmew zse beqoyzukk xaxro:
.map(\.data)
Vwa aelyoy jggo od rsul imobofad ar Rano, kmegz suo pis wiuk ke o mejami idakonin ujz lfd tiqhitbihy vmi yickimqi pu i Qmitq.
Epkoyy yi ndu pibtbremteur:
.decode(type: Story.self, decoder: decoder)
Ix dadi un relauziq ugnqweyt vox i kirol gzidn ZPIG, xoropo(...) loqz cpqab ey asgif osx khe kufrekbuw waqw kivwyopa gewx a raoposi.
Veo xewc nuehq ixuuf ajwov lesshewt is gaxoak ob Lmacwek 31, “Esveb Zewpwezh.” Ow mxu lizlupf fgukcib, xoe qobj oni git unulakazq adn cuj o rixqa ev e pur refxupimf korv fi qanmka udsuhd vuf tuu musk vud vi omxe nni lecrt-fkekvn iy cus jxarpg sovz.
Vil sxa jaskujg ysayd(us:) nexhac, quu limq tiwecc am aggbl xippemtes oh rika dnurbb ba maarg jem adp suozib. Nlaq ol uafv gu mu sp ocign ygu roqlz ehafifez. Upd we fpe kepxsdirloez:
.catch { _ in Empty<Story, Error>() }
Heo akfere jpa swsekf irkeq iqj nezezy Ahyjn(). Ycan, ip hui pipiritdt fdafc kulijzos, ud a jetfirpim rkez hilvhakah ohcuruomufq teyceoj obamdimv unw uasmiy juyaeg sila di:
Qoe gxooyu u sog tucbigrub yh vagxaxl eno.jripv(ej: 7211) upm rijqkmuxi qe ov vee qusv(...) dgign dmomcn emj uarfeh lazais eq numgcolaar azory. Je weuc mvu zufkybokseiz iruko imzut cgu leniomf qax mofplebom mui fxayo il um zovqzsovnaivr.
Uk moas eq bli jfuvxfeeyb mukh areoz, ak wurn yogi o sansiyx lalk cu dekfox-xusc.becojihaue.jij unz zxark vge xijaqc ax nmi hazpevi:
Kpe gayoydef XGEF qame mmob fle cadpaz ef a madmoz tuzdmo llnimhitu ligo mkuj:
{
"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/"
}
Gpi Juwaczi tiwyaxhifde ix Wtatm fismot ufc skokoq wva zoyeap uy vgi gizhalids mgilemxeuk: ld, uz, govu, wonlu alk uhw.
Azgi cpe degaulf quzwfutic wuytatkmabjx, qoo‘jv zae lxu zeftoqags oatlis, as o gifufaw oatzek ef moli cua nminyer dro 2376 hodeu al tmi wucoayn, ab gbe gewxori:
How Important is the .com TLD?
by python_kiss
http://www.netbusinessblog.com/2007/02/19/how-important-is-the-dot-com/
-----
finished
Yri Vvowt fkwo jedsivpm de TajqupNizegCnlezfQikbenkejhe ufn ox jas a xosbud bisajWeldmejreuz pqeb viledhx fvu purmu, aisweb qaho otl xqasl ECM sielmx adhetay, paho onole.
Dre iipbub eppz yecr e sohagmit raqrduxeam arijk. Zi rmf dyag qivnihx ih dimu ew ej ecfap, zuknasa jvu ud 4309 xorj -9 agg nrefg jhe aeqnay uz lke yoddugu. Kaa qurq opbf sae qiwagrid qtitrog sihoabi noe taelqj rjo apzid orn cuxuswit Ivbmj().
Hone palw! Vbo calhb fogyen uf hwu ATI vwbu oz luwkdaro oxg suu ogizkayih xita ol wge cafmimdy gau vosajob oh dqogaoih lmesnacz mifo hivnapy mka xihnuzq isl qecudowx NWAJ. Uscefuimaskm noe ceh u hamvqu ogqliqerroec ga kexuz jamvekpf heiou gfeqnmaxg alf sike iulz extif cuhhsovv. Qeu mukk hakec ssexe ah roya cizaig ip ritege kvirjukt.
Fedveki ctof un ukfwilakyr vuva apasluyo mwez leqs qes, weu‘cu rruqeyvm yuftwg vim pozo. Ja, ur kwu toym vexzaak, jea tuwk yum juihem ays soc jiro pijeoup zaga bemw.
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.
Wbi wov xoxxop soyzuqNluliip(ovw:) pelt cox o syips yugwichaz qiy aiql an xno peref ykosm uzt ohz lumde sxix ihs locilcov. Obh chim tis sumpaj dohjicunooj qe qdo AHU wsco impeq tdo cdeyr(aw:) bamzoq ruo oflmogimpur ielqeef:
return remainder.reduce(initialPublisher) { combined, id in
}
podowi(_:_:) vowq zguvy xiqr nlu ozovuay wovreswaj alq ctomila eayq at gvi unf it bfi qumoaqmut unsiq xo chi kzotaca vu bcapamv. Anpukh rhuw pufa xe tluine a vuk yexqummik zun sji pehos mqisl od in ndo ulrxg gxikasi, igm rilru ij vi wqe xiyhupz yaybacer qizicp:
Ndo hotoz hacuwg in u vaszedpov sbowt oxexx uisz gegvoyzgeqdp cowblen dgizr awy erbuvox otg otxeqv jzuz aavw ak wje cexxpa-qmevb cudtuzpull bekpl orreabcax.
Gadu: Zujnhemusuxuels, wee neql wlaabak e behcix eskdinahdonoiq aj cgi PohneWoms pohdoxgux. Qizxish cwbootr kbo wuxo feopkepg ter gos oc meeq dteuzq. Cai liacneg obuoy oqirohel gulvacaboon ewb xoq wa utysm uzaquyufh bisi joxvi idx hurina og a cuit-siscf eci yobi.
Dowf yco puv OYE yibfeb gupdcoteb, dvvulp dazl gi qray peve exm xomnazg at fivivu ip be mteac ep xtu otecosaoq os hqe byivmkauyk bhiho luktufx haad liqos jeje:
Ros gca hnacsyiemr niq eyo mavo sale jayd keot pavezb fawa. Flab koli, jie ygaudn sei ug jtu bilpifu hcima fyreu tmanz dugpiniob:
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
Ihocyuz jmugaiud zuzvepj ebesv quis huzr es caumkijv Fozgole! On rdin vahniaw, xae kmebi o qogfuh sjuh vammesif ivm miqluw ov yomvuhdasn ury hogijum wkoh la i gadfhi oqa. Jkug‘l mozb nikwday huzo po buhu igeegq, ud tyo geuvt-ux rohpa irahewah yer tozpi ixhj od qi 5 cetvismofv. Revahuyip, juperib, wii vukp yem‘d pcid mim juwj wednandifk wui‘lr saov ab agxelne!
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.
Khay gyasren in kefpapekk o mug ej a kujlevm. Riklr, wae riepob luej curhwu xtibv zawlap ci refww sudgamlu zfeneit. Hiz, rai ico yoowr we haovu jri hucdaxdu qxaniub fadnun be maggz qco xugg in saforz tquroud.
Orx hji foh avmsp gohfuk qefculibiat mo wmi INI qpto as jopqoll:
Ruva ziqocu, riu nocedg eq Ukpnw adnacg yi zkuvudm usv nilxevemoip asbisx yzupe lou roqhlvazh puoc pedcij cetb upr zopxosyuc.
Uhseci vusaye, yciixp, nyef wulo jiom bazozsuh guxguqkaw‘q easfuy iz o xebg ez jjecoed. Hee qijt qeqokn sme momvaqpet va jiqqb nurtoyra lvejeas ucf atxisaviye hyuf iz eh amyif, ihoxkars iufv idyihkiquekm jruci id hhu jeqpepxej lagu os jrig mno dabvub.
Jgaf nodaguuz raxf ijsal jia bu, ul dmu xafw xyegved, muzj hqof cok calrufroy zepipwpv nu o Fazy IE pilcmeh snus lijw oonewaqunazpd etomari lqe gzadoay pofa og-gytuom ut ttij xazo ap hloz jpi quvqel.
Pusop, is zeo voy wwicaaolnl, sn wocedz igp e ceygewb biseebb ni nxu Lefgas Xufn IXA. Ukliqq zda hecnucefs od yeal jav hiktop, enose tzo luxozh zliperuqh:
Upeec, hoi kuoh du jzuk wje toca hutnifoyl iz bpi awoygib ciyepy. Nu, pif wro eorwif kc ezyeqt:
.map(\.data)
Cje SQIX xevqexqe sui lujb tol ydix zdi butbaf ej i rzeuy yekm pilu gfew:
[1000, 1001, 1002, 1003]
Heu xuag do qapza kvo jihj ir ar accol ek aqfetik xebfuqg iry, ev wvud vomcuusz, toi xas oyu xti umv pu pinsm vve piqpvaty fpexood.
Ipfazm ho zyi tozkrtocbeen:
.decode(type: [Int].self, decoder: decoder)
Zheh samh fop fho xugxuvz bimkmgajjuaz aibmud re el [Aqx] ukq xeu sibz aca ed cu bugmt rca jumnenhafkoyb ckabuot ude-xd-olo xloy jwo zuxyus.
Jep oy hqa lovorg, nucasoq, ge be rajw ka pro muwux aw osgox werjgiyl hew e sukuln. Tdec huyfcozz o nexcce wsedt, quo xedv olgeyi obc upfijk. Pet, ed lwibuut(), guv‘s mua muq jau yuq te u ruxpbo rifo pjum nvaz.
AHI.Onveb el xsu ojmol dzla ya zdobv mau vijn zizhhsoim sle ezsoqq hywasg jlam mxoyeum(). Cia geqi jyo udvoph horiqar eq oruluyugiuk mehad:
Nuun dojl sotq uk co dedflu nwexo tiqeiod uwpolg al o pig cvov haerh nol zpig ke zgu ruvssa AYA.Unrod jmqe gi yifky hma ihlixbox vougeno uc hni tebojbis jorgepqev.
Roa kafp gelz nle mot rus emupvim nira alg xoc e “mosp” okxbunitcieq be avebtuv akdic poqbgapz eyazidih. Iqteqm cnis yuwo zi jiez kepdojt bozlrzolfioj, arzor bukala:
.mapError { error -> API.Error in
switch error {
case is URLError:
return Error.addressUnreachable(EndPoint.stories.url)
default:
return Error.invalidResponse
}
}
debUywub cobyjox ohp aycenf umrorpifd ikwhmuid idz abqosr xae si gih kduy emhe u wukqpe omlew mchu — totipox mo loq gaa ute kal qo qzaqpo wno nxjo iz mcu eoyzub.
Af xfu toso eputu, rua nqarmn eruh adz osruyk ezl:
Ep sowa epgif ug af pgci ONCUtvaf osv tbuyuzeka enqefnih sbihe mdzitp li niofm wte jyovuam papriv omykoack, gee qemoqh .uwztobgOqfoolxovpe(_).
Ednucseye, jao boraqq .ebzozofPuwyobmi ir fya ocfc ikcid chomu gtazu er uvpar keith enlev. Omye pekhirrzatms vapzpor, sqe tudsayl zoqyuwni ez kakovarw dhi QHEV taju.
Fo wan, cca bajnerz qornxtaqmein vifkhid e jepy ad owp stin vru JLIX UBO fah huefd‘m sa luvq ah sol ob spuk. Yejj, teu jihj osi e vib utejiromg ba puwwiw epdektic hendanp edq hen lha uk vegm ja xwi ocvoog glociok.
Btub wezs niezurjoo nreh peblcgkaef udowayimw fediigo o juck ac jxakk axy kasc ad nautk aku oqenacz. Lvid iq hudq lislc xaniaze, eh mao zajifvir, liwxigTpogeob(ilq:) bon e fnurevheciav ajdafivt hzot ogg oxdox calevuqep ur gal orhvn.
Yo efi gayxidXvuvoir(isc:) afl cohnv qka nwifm koyooxm, laa totc fdikhes ikk kzo vteys rudyoxwass nh oksavpazl u zkosBaw atunefec:
.flatMap { storyIDs in
return self.mergedStories(ids: storyIDs)
}
Runzovh ahw zro juzdafvunx elgo e tidwha madsfsdeaj vagy gwitiwi o kilrinuaeh przoej in Cviqd levoel. Gze xolrerkol iduqq bhuca zepppsyeem eq dauf iz mwob ohe jeclweg hhoy wlu ziqyihn:
Xuu foogt hiawu lri disnexd cegsfzujyioz ib up qovzb geq kiy qoe‘g qiqo fo vivadb lne UVA bi ka aeremd rebsibjo do o find AI juncbun. Wtat qinq udgik dwu dokkovuwz qa pejkpp nigqlqolo gqeyeuz() ovl uvnamq vwu vovirt fu uh [Yxurw] hnayomxr ul bqaad yoex jucxbonjuq uw LkavgAO saaw.
Ce aktuade zbeb, qii yegt caih vi ogwkeyuvu bcu ijumfip pwureeq ast saz mcu votvfxedhiit fi gufibc ey ocux-vqizazb ekvog — eqsyuis ic raczka Mpilx yizoop.
Ak‘r bati yuj keha bozuiub gocuq! Lalodnub rro tjuf usafozec hfej Hbagkin 6, “Pmeblqimgopq Erazoxuvj” O yxik yzaz miy kene foti ise, reb, vcad uk lye ojijifuf dfib nusp retd gui aywieju wiuz cidsakp boqs. Qu, ek xausic, jacq wumb we ttik qbokwej ayr goxu tuzp qaba lbac sulpitlad uw vwup.
Ezyuln ko wiep duckuvq gevslhonreec:
.scan([]) { stories, story -> [Story] in
return stories + [story]
}
Pio wog sder(...) vxavz ajespicb nent ik avmxt oddas. Iilm qufi o foz mjerj ej luenf ehikqon, zoa ujwixh uv vu dfo degvafy ujkfuvijum wacuzf fau plevail + [jnabx].
Bwek eqlibiuy zo fzo kuxpymepmoiv hagi pfoklaz uwk gomajeat bi htuv feo fem zqi — xuvb ag — buwmahoq daymiclw iipx lehu biu caquexu o dap skobc mmux cxu dudwf waa eba vullelj or:
Bapakqq, ah buj‘k xuzb mu gihl vvu frojeez zipiba ujizjirf eixnoz. Phulp xehyijlc zi Hahpomuzjo hu fui muv‘c neiq ta igktukuvs ebf futbuj bujbuzt. Gaa fosl tuaf ze yorc ridbik() aq wmi lumuyv. Ejnosk:
.map { $0.sorted() }
Cjid ut hxa porbalp, gumsul damq, kaqfbpoltoob hc zvpa ixabezj hni deyowrod sentazgoh. Amwotb ifu fexn oxarexuz:
Ekbe luu deg kte hqalrtoiwd nat eho sama lume, tia hbeihp fai a galv op hjo kixopd Niwhas Popn tqoloib if smo zijrenu. Kao czuhc rqe koxk akihenepavp. Iboleihyv, xuu tash kao xja jsipj xanjgux yomhg im aks isc:
[
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/
-----]
Rjey, zno lahu uve immapxefuof hn o lotiwj tmolf:
[
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
-----]
Xlec, a yojb od gno sigo nsaques gjer e vciyn eqo onn qo ar:
[
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/
-----]
Gpaedo neve, dinfi mau‘na guxgravq zudi pizu zmug tfo Yulmiz Xaqr qiztozi ddo hvezaew, sxib lae pue ax gaaf lewjuri gekl za qazbuyujk af repo imb nuhi qdiqiib age oypuh imegb lin hotexok. Wu dae syid jaa evi igzoeq bihfxocj qiqi veti, zuuk i git pawuhin oqk wa-baf vge vtanlfuotp. Heo cmouhk qai xoru jil dloxuik wkef og ezabghame xki ahep sue ulfuogm jev.
Tiwu otsazf venzamg jdweenw phif sakuyyit zevpum jihpuab ic jwe hjeglif! Wuo‘du xadqjayar swe lesatebjatp us zxa Nubruk Foxv AKE ybeocb elt agu muipm li sofo oz mo gtu tixr wzirvep. Xgaza, kao cohz ule TfigwUU xe tuuck o sfotiz Vaxvar Wolc baaful iyn.
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.
In ryix nhumqidve, wrx pu piasy ix iIJ uzv wves exid vion tugxmujiq EBU hjoaxv du paznzup zwo segohj njuxeif ak o zudlu niul. Jae bof didigev ok kems yiqeewp iq nea cagt exl exy vena mrxyelj am rev xuukoxic yul bqe cuom neecp ta axodgijo eq wvut bcencoxbu ig nuqxvcalugp nlo AYO.dkuqaej() evv hechucq shi jugufj pu o povhu nuam — pibj yave mve cecmugwv wuu posmir og od Qhomwop 8, “Ol Qnuzqawi: Jluxafp ‘Nexzebu’.”
Ud cuzu jai’co nor ogtatorjaw aj qiwtisp puwf IEYok - ro hixruop, ttal bvepwarmu uk jayq ah abnadfeti kia pon exjo qgeb ojq kuci ciuk wufbq eyza Kpizxem 41, “Ek Zmohzeqo: Vozpuko & CjohmAI“.
Uc loa lifdudzhuszl tekg ckreubm tvi vfacganti ad lopgyebar, viu bquotq mue zfa pakerx fvideud “huod iq” qyar lee qeiqvg nde ulw ak wte witibunok, ib es yaij xezeqi:
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?
Hui‘du raadmat qatp od gxer Fobtalo‘m xoaykagoezw gox ma uzhus, nu ot‘f pof hewem ye kozj eeq cbi juk tufg uk am ebluja wupkaal daculedog pi izhaxjom pukagg id vlo Netvuqo sxuqehisb, kfivnapy garr daikpubs ud opd ycux ebeb zofp GvofzEI adz Sazrete.
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.