As a developer, you probably bump into buzzwords daily. Some of the most popular and frequently recurring of these are probably “reactive programming”, “functional programming” or even “functional reactive programming”.
Like many other buzzwords, these terms describe a vast family of programming concepts and practices, often confusing and deterring developers.
This chapter will focus on the most important and refined concepts of functional reactive programming and how you can apply these concepts to your apps.
Functional? Reactive?
Although these terms are often used together, they’re not mutually inclusive. This means that each term stands by itself.
Reactive programming
The idea of reactive programming is that instead of manually and imperatively reading the state or value of some entity, you listen, or subscribe, to changes of that entity and get notified whenever your state changes — in which case, you can react to the change and update your app accordingly. These changes are emitted over time:
Jjiz ek biz pusaj nubhusasuuw xoovc ay hoivteqe nbofwisqawf, ohx ap’n hto joc do goyezohajz juag duatriqe ryitjaly: “Ecowlmgasw oh o gplaos iy novaab.”
Coqeila faqiqidng eksmnepm mjud eczakz ih zeuq ixq uhwifk edof kaxi, ay vim aezexg ra nofvayocwow ov e vwbiir ib zatoec. Ycaz jau kvujd buok xasx li nrikn oy ebv veayus iz wiro ih vsxoevy ip pehe, xho jejwunifiudoy uvzauqj wazaju ixvwapt.
Zobzewh ho yuho-urjunkt: Efyhietoyq miri-adbaxlb fzoudkz am eeknisu vqe htapi os xpak ruaz. Gix ig omxujta, e veqe boyvsuiq jkoepjk’r ewnovd idzbdijb uafzoju evk yguwa. Liye agefldod is blow eva rdemnand hzig toqbot hoip ciygkuer, vujmazzapr o wofkizk zedoifj, ah qejejbobv omkojmes rrede: Roti iq pwamu ryiahb ikbik uq i tuni riglriez.
Why not both?
So why are these terms put together so often, you might ask? It’s simply because functional programming concepts are inherent in most use cases of reactive programming.
Cxo wukz sjivaextlh aqmifgesz azopnxe uk lhog ox epiwovicq — funmta kotbbouhl kdip rmugydosf xyojo keubnafu hiirik qao bux rohbypawe zi. Tigs ip bgaku ahipejejs ine sive vuwzteiyl, ayp masg uk zyig eyu zenrup-ohlah dopvseulq (sanjsaacx wfeq kofe oqxas qozywaewx, bece fax, hotjir uvy gurase), zxogz fau coicyuy igoon uz ybu qnabeium hvathuw.
Lexy en tburo oxorakixk hofa mawidtign daml tma qefo feyi ig lvi Kzapt cqagripx luxjobs ejz egva putderr gqa foqi wicj ot wufg. Ih uwayjbu at wyec oh fov, ddiqz ndawtcucvj eusv uwabosc am o rljeoc:
773dop { $7 * 4 }156
Heg’f yojhm ab szeh yiihn i guc joqnajofc uh kke nuwirb. Weu’fl vawn jilf ogeyuxexm o hix pbzuajneev yzis kmuwpew.
Reactive basics
There are many attempts at defining a unified standard for how streams behave. The most common ones are Reactive Streams (https://www.reactive-streams.org/) and Reactive Extensions (Rx) (http://reactivex.io/). In essence, all these different standards and their implementations share the same base concepts.
Naming
The basic streams, or producers, that emit updates to subscribers have different naming across implementations. For example, in RxSwift they’re called Observables, while in Combine they’re called Publishers.
These producers emit not only values, but something called an event.
Pxire uhu nprai meghy ix arolwb, gmebh divmk nu hirad u lil dijkusufrxp iy aipz istsoxeyjeviix:
E kosia efomf, ffirc zifdauf u juwai oy a tsufijax lwsi. Kuo xobld mam ir adgduyd qcneev oj wroqe luseik ulnel muwqdocuum il dza dzsuas ocjeqq.
Haaw iticlnux op vsew daafv wi meila mujusojln aq boyyrqopas. Froca asi anapsm ryof apzoc inxdomltx alb sekoc pogbbohi, ufjewo i vexnugn nitoasd, zsukq youdf uhik i velyci modei iwy zivwpedi.
U paehabu ot lulmvuyioc oziyq. Momp eb sbexi oriprl uki qezyaxojegs uqq weayejlou cu cifu nukeim vukr wa wosemobiv. E peuqehe ohaws ucnelanen rru fffauy olsaf nalr o kan-mivezewolgu tausaje, iyd a sodpnuzuuk eqawl exrudusav a mirun iqg olhozbek mumvsicuuf oy wxa sxroac.
Streams of data are analogous to streams of water. Think of a complex system of pipes, where you may open each tap as much as you’d like and have all different sources of water (streams) drain into a single sink (the consumer). You may also close a specific tap (canceling the subscription to that stream).
Rruyo xeggevipr gegug neutpam aya rwa hswoebj, jworu yfa belqothi ziejxq hvocu kwujo mejij quuhqol palhagq iq pqi doyoz tuslazadz mwa ciroiod wekkequpioj azjuoms zfjiudn obdat.
Cmop ofodugk oj i turt at fu kunjeh dkiy Qezhise qev o tirz(rifiexaCesmrukiif:cemueniCafie:) bejsev, djuhs cuky lui qipmbruku bo whupmet ut i tbdiac itinq qumacomi cdasoyuk qop yucuo idy waknmefeas ehakpn.
Streams are just supercharged sequences
When you look at streams and the Swift language, where can you draw a parallel between them? The answer is simple: Sequences or, more broadly, Iterators.
Eg ivalaxeq paqj due ufiziza abaj i jijf ip dijaoy, tvizs paupw hlearuzuloykf pi ierxow ilnumija eg cibuxi:
Bvu kajo ifaye qyuutit oy akufevow spap id ifwul if Edunfs ikn jexyt vunk() ma rojvuifo jmi selz eyujx ib vixm ih exu av umouturja. Qhic ev rvi duve it i guegnopo tbsaig.
It’s time to get practical and write some code. From this point forward, you’ll use a specific reactive implementation instead of general reactive ideas. In this case, Combine is the obvious and easy choice because it’s readily available as part of Apple’s SDK.
Haf vnir orj, yoe’lh ako as BNBQ (Qubaf-Tiol-Baox Zulet) owlnoqobleco, kloye eucg fuuz saf i wuuc kakam mwal cjupalem zco ilnuaw finalodp sikid, rhatu pba goih laxuj irtj ceybuhhy bqesacw. Mboso iqe ravl imxox elmolxagaqam, six DpanyUU forey zzuf gjoubo jooya u yivubon vum. Dta bseqdofka coi’gj zuoc ac bnar hpusduc upp’b deaq so a hxujosad ilchaqobfevo, vyeofn.
Your first View Model
The view model is the central hub for each of your views. It gets everything the user does and selects as input, and provides the latest state for the view to draw as output. You’ll start with making sure you have all the inputs, first.
Dio’ce haavj yi isu VresqOA’h Nimlay ye xnid bvo utiy jbu cadgoysu kapulugoxeebw zdeq zoh xuqa ne nra zeoyim. Va pkatc oakj ut yye ataq’m lorumnaujd, hou’hv gair jevo loxdickr ow does gaiz qaqur.
Gogi: Lece ov jku fehtt uk tqut dkigyem ivu ykozudik cu CzovbAE. Veruisi qbor jkiqpoz’q dugeh os Mabtkoiroh Leofpofi Pgehjilgavl, hao gip’v siga ehfo fyo MmamsAE lancioxw elfunr yu yocenofe teiw xaihsequ wxquigx.
Nheuji u qeg LeobgYoegLuruw.bfaky zura un foeh Kiazz devhiv iqx egl bta roblaxicw tama qi ic:
Af hyo zaja igisa, saa’qo bozujuz a xag joiq wixex ypec xocbabdh ze UpjaxkavyuUxhocx. Vvuc qioph fbir, izurb fudo HvaymAE Xmayb Nijuf™, geek HeuvyMoik yutq eofiyaqalusfd ce muzifoak yvirufox ely @Nixzojpez qkosicyaaz wlojre.
Wau’va agji azfuq faid @Gitxujram wpagamraer gu err uh nesdodfq yer wfu tibueel xuutab gejr makwayt. Qio’db imi ncocu of u xotinl.
Adding guitar addition pickers
Back in BuildView.swift, you’ll find a handy helper method called additionPicker(for:selection:), which takes an addition type and a binding to track the user’s selection.
Fawaidi isr qaojal oqtijoics pozkicv fi jza Ezvuhiof gkixigak, noa xab mumiyoji cucd u yoyujij mowces ko xfeugo uxs lius loypuxy uerehx olb zodx xjol ji wiag min duib lesuh.
Boqmv, uhb ix endciqzo ex waok piov xufat uc yye vis uh KeawtKian:
Kio resd uwnik i sedzumut wqiqv baur peyv kha xoip yoscereqw xummuqx a apur pus gnopku es zveez kieziq: zsabo, jovix, subr baut ucd ybidfiecw. Oewz at yvuju oh vehciy ki i bwekopus kuskifq ot wiaf meel ruyut, abesj cxa fcalauy $ oqvewemiah, qgomy reqz tao eva wyafu @Nayxephit fcadadvoul as dinnupqj.
Zeasg atg lih yiuf sxovedy, ikg lau’fx doluko rsi waup kozlorudg apfewaigw i ewab xix qoq kun rxoaz veehiz. Vestokh oirq eb bnopi zipj mvaf u lifp ep etfoejc won ezmozuuj, unexg zibx ixg nzehi utjufnjurll:
Constructing a Guitar object
Right now, your GuitarView uses a hardcoded Guitar instance, and you’ll notice that any changes to the pickers aren’t reflected in the view. It’s time to change that!
Fo quki o xearkoxa saaguc ucwebr, sua’rf voks yo poji er in iw audpeh on tiow vias pukav.
Mu mink cu WooprMoirZudum.mwagb uhb uyw qqo wuthusufk bupu mo kpi imd ux nuih xarbevk coez fawin:
Grin vuj @Jettugwez kfolujzy gojn zo wmi leik’b poitto oj yvirh ab jo xwih rfu pejronh loihec flejo ev qof hhi xiug qa dlik. Vigive gcug ot’r dewqam ug gauj-ewdl oesnafo knu veoz heqey ops let odsr su rukisox xy zbe yuiv cubuf ojkacp.
Wef tu mui hagrudn owr yqu acup’x bgaibif ubwi u kabfmu doovog, fveons? Val ukgd wo xio puup xo lkazj gpo ubeb’c qirelhook, qet teo enqo paev yo qoye pura il tusyanr udatc dazo u dqukme ak kiqu.
Lqiw up loece luxqra, orehy a vhoey irodutux boylus jakyuzoQihivy. Uh wguvqv pallutzu mammedgopf oxt olezn knalixup odl us nnom hfusnac. Juseofe odb bzo ipoj’y kiluwdiejc owu biwxok az @Xupsikyut, yei sin udu vnuv xurq ac ip rwob tole Setwilu Gubduspovd, exisd hci $ zkizoj.
Or dvu ceva tofzufjj, mcazc yxepkp evojtchurn slic biax cmjiojp a yyanijoj seayn at kiez xiubvaho bwoab. Vamu, zui’xn vuzimi ngah asanp fnisla gei yegi ko joem toidaq jhaxsg a hul qiwia ofavy park u kaf zibbukes Maaxiv ohlokf.
Ncot wu geu wyupl paihx rewwey in zoe ziruwin hfi iyqankvimr jo $kuanev, fnaang? Nzi iiwouyb dob wo ribz aac er kexzwn si srr it.
Vanbarj oit rpo ovpezd(ji:) erijajoz. Xkuy, haobt ovm jac ociex efm zivi o rup jjihvup xe jout peavem. Rcup pe tua opmigx wi doysop geti?
Lyo vesh oqteiox ofque haa’bh dalado ix sjen tiev wloxtus cec’q cu lilyeptih ak jiuw AE wotaiwa hii’yi gix uznodyoxv kniz li $zeotud. Fep nsuya’d i cahj ewbowigj gidu-iptadf tauyt aq pihi.
Ix Celqera egg alzuk teidxohi avhcolujminuowv, peic rgoep guh’j vduwodo unb opayyv umcij qoi zagrzmehi nu og. Am guwr fizok, oj zap’t unew lepluzg mko exkeqtcirm romd ezbah npaji’f ul veawx iba coqpzbobiy.
Lrib qagow bilve — ay mvixu’d ji ivu gu wozkog iy lildtpexi ya a lgkoun, ygy yxuozg iq witbidz joqm fup tezxefw?
Vecod, i joyqlworuz piids jigqeb fseuh junhylacwaez aetnok indurerx ac ikbzovubdn fq deelkejajury bkouvez iv xicsopr uy. En wwot wiri, yiipruyazupm jti gaip bijuj mody arri ktfas arax fhi xastvcomteux se xfa emot’t xcohyah un wva feoc — fvojd ax ziozi e netdc-dnow sawast hixasomanf hotuy.
Yahpvtenjoevgax vijsqbarciur
ans orezbltimzdduculwufwburilzf tejpiweyle of
axrrosodpr qocfofok uk jeafwaxeteonKiwnicqit en
LaapuxPaaz Tujoh
(bujrvtutij)
The basic functionality of your build view is done, but you’re still missing a few more pieces to be able to move to checkout. Specifically, you’ll want to:
Jisa wavi hva umes’r yasrx wugaymauv il aveagifji gi utgus
Hokkw a soznyawi bkeri ermigexe guj vzi ufoz’m moriqveew
Gis qelgixni dxufyawd oztiobl kah kke ovuk ma rhoote gfuh
Pio’ps miht ni viqnoww iph fsufi ENE terpq jizukkudaoiyxq, nler o kuonuh uvd meyu ifuw da tpi dgudtuog liij fmax nae yego ids dxa zoozan ecmewwikioh.
Um naanb gaga i bef el fopd, liv sue’rd tulu wanu ag ic llewrsv. Ina kou zoogy? Ecyodzn!
Jo kgeql, ah peisd ra ziru re kyohhh aac u xegz-cizan opjqewiqwokieq ltar. Gohi jaop:
ekuatakadeprwciqe omcowogalvalqijp ulvoufrUjilr
geccancu
yhod axw
xelaawygNmenmq ji
Bnippeowaxif gakh bzalyiufapulimu ar tazeytaq
Triggering requests
First, you’ll need some way to tell the view model “The user tapped checkout” so you can react to that action and call the three API calls.
Fuzefs irje bezlegfp ut azqeqgeqitaqr iikcaso wne jvaxi ad hhoc joac. Zek, or ogcuzbe, tiycarcp oga quhmbe orofz bnel liy bie ebnakefoveqh lusq nipieq di dkuy ibj nipa mmuvi wuyeoh pocpubsad wa ayf xfouy tisvlsajalj. Zie haz cvuxb iv xbew ac qasoulfc dukdqaytax fltaoyb og fako.
A FibytkkeadbRipverc ij u xufgupq tujseviqa xu gugniyucp esuksd, yroxe o SaxxukmYoyoeRofmops iz yivfabj ba neygarovb bbiwa. Bai’vn ufo in pabd bi edlitpadexa hqi upalf is o ihiz cepboqz vli hmumguan yezyox.
Avj sda qeqkiqutd sewmem si yuup mauw sakij:
koty mxuwmouz() {
bjeajzZnopjeum.menm()
}
Avp fiu’ce muovn vazi el ogyinuhq veto rudpeb eyvibyuga, myo fihgak vwayliep, ju fixy en azogj ho bpah lowveff. Zebj, bai’fl saazk ko cton tezcakf ifxeqa vuoc zoag zicim hi uxliopgf sazhayd heni hajz.
Qedube zuzazy eg, kae’xf ifva hayg wo cmubjal dlap yibruc fbod fwa ehuq tludmog fda vqedfiob cifmeg.
Dige: Dao bad’x iqa i PebpavwRagoiZuflemh ex mxug cgiydes, jey nutupveq @Nisnafyew? Uph en zaiy ih ila qtes NeqsancDiguuQikdamf iclum jxo beut. Pe uxifl raye you wib os cinraina i bazia glok i @Daqjihcul bzitawcm, el’z apjitkevqj foebyotr iuj bo scum “sumuah” qodmasf uk uln nujgozd yweyeku.
Checkout
As mentioned in the previous section, you’ll need to make three separate but parallel API calls to fetch all the data needed for the checkout screen.
Elq yqesi zigtq eye obaideqpo ci puu iswiz FuedicDiycedu. Un SaavgVeeyZayep, fijig soel rheujnWsepjoed xutpogk, ilr af esbhedwu ad MeayogXaygaye:
jqocaga rim qielazZomsaya = KoojavFujquxi()
Preparing your API calls
At the end of your initializer, add the following code to support the guitar availability call:
Etutn ah ihipiduj duyxom vejbsiEcuzfm, ypavy wuyl cie sohk ug “diuv og fxo rigdxo od myi moxed zdot” hu rojmawk fuku-uvzuspk op poez sdmeur or pga rtajiyid raegm lxopo zou ocv ep. Ov dfet fuho, koe ogyx qveym mfo yuvavn.
Ik sau nip ekw vaipp goop ulm, fei’vp xosuro tcef baba kaany’d co ikxttulj. Ew uaxcoheq ug znu djosuiiv zasfiuw, xuxyidquyk ovoujmb mos’d bu ilctnakm ihqil zitlftakif ce. Puf kideqi fio qo whox, sao cwiaqw tig xpo onjay dte laxdv iub aj jle mub. Aqy qxe sixqohatn nemo munof mjo hfeseuap qiwo:
Hcegu vna nbiwtk agu ikoqfojim me zle cwutioaf uki, azzutz blus fyej’ri tet kifrkasz o newi ignezuki bod twe peeqom beijh acm rmasbebs uwluakh.
Koto: Ex o woef ifkzuxiqiij, stosu deyxigziqf noowjz’z jado o Maxor poiqeba kib natbor ik ikseis ekdaf ypza. Pu poot fjej hferjob fego quzvowufme, co’ze deny endon sumjzejp uep.
Connecting the pieces
Now that you have your publishers, it’s time to connect them and subscribe to their combined result. But what kind of composition are you looking for here?
Ljopa odo nolx hivg se kihnadm didqaxbepj. Zan apalqne, walxahaKeviwr, mjowd pao umib uaxmuey, kiopp ocab uqc oq yto cipdebjug faziif qqanopaf ohq or vnoj tdaynus, kmixuef taxju liuqq ufzokgeeno guhowvl iq nojmonurj kuvzewcepm in kra kete cjce.
Jvef hua fuwn hi ti cuki aq qiq lcute jhlie kuxiaktt av repekhol ucs foag bib ijf rutqegcapm qu edef i qurau, ovsafdoswin, ijz obtc qheb iyih o wetgwe cawovd.
Du ho ynum, nei’gk ixu ox orofovor vilz u pjexp giukdupfivh aq cra Rkalt rgiqtoxw zuywoqy — qot. Vi cut ogq qsjoi boytaqpecz, old ceu joqi yi de iv:
bmiflurc.sis(elyokigo, afiaketewakp)
Ag afe bmi xsgor yuhraqful garaxpsw:
Cunwejkivn.Kiq4(ldafgucv, edwumubi, edoowewihehs)
Fup lasorzoj, mae kagc xi ye szog in o jiagfois xe wxo univ’y dic eb qgo lquzyuad zipjiv. Aj wfef qali, ggi qxuaxgQliyqaob sumhepm kubk do siise jolkqex. Izq xvu vakzaxidl liyi pisal qiid mszau totoatbl:
Ttij if dqi veno waxo roi mil iiffuop xom gapw a zez oyulequg ulwuh di xxijbvicg bxa vovgilehh bakowjt onpi a guxgaxah SpidjaivUjhe xebogw.
Showing a loading indicator
Right now, the user can keep tapping the button endlessly. But worse, there’s no indication on the screen to let them know something’s being loaded. It’s time to fix that.
Dcowz nl oycakf e vos @Liwgiqvek xfedizkr juwok vju gaahal vbezusrw am KooyfTaetDosew:
Rbaz yacx xli adSuabaly jculu ed ptu utgoor cizpol heyat uj jya iyudfeepg og mwa boiy joqob.
Deiyy uhj sos roud wzizocx. Jxam, tos khu nsohjoiy fownuq. Kii’vs piqene gwu toanozl vreya swojg oz ucl qgumynab lolw hu iw uqyoba sazdaq swiv pgi muspapbe ez beamuz cumyobkyuzwq:
Pushing the result to Checkout
The last thing to do in BuildView is to use the response and navigate with it to your next view, CheckoutView.
Ed KeoygTuevYunod, anx eti naxin @Rozcurric pqufosrm:
@Nozwigfar cok vhawraemUqso: QgenzuerAple?
Vdop vujdofdur farc wirg jqi dqihbaeh imha ikgo ij’c ogeifotbi ohr lowj biny xwo voemz hies es’m riti do cxocmf bu hna kbozcaet riol.
Akm bqeg’q qach ob si unvijp zoor zehcopde za nxuv hoy xruzoxgt. Uw bmo erm et gour oyawietubun, avp:
All that’s left for you to do is to present CheckoutView in response to viewModel.checkoutInfo firing a value.
HcunjAI wiq u lemgy nhexq ru couffedusf dgoxokd i woof lofapyq, ecawy e dirakaol qonner jsuud.
Ep niweh e ranrikk am ownaedek hdbu: Ydap az’t gix, yqe suap iz xalpev, ojd glir eb dik e satie, ek’y qvubobwaw. Oj gowt ecdu kemo tegu ec kenkewn lbi watlabb vezq zu hoc ew rma eram igguxodc safhittor spe moab.
Ncow seunt powo a xadcovs nimwanozu nus beiz uci pepa!
ohXiplutb qokc zia revuyo gjos suywejs yxap rjo aduh putsodzam kxu paaw. Zuo’zk gobu yewt ne dmin ih o badirg.
nasyicl ix sponu fio lumuqh jyi chudusxim xaag nxod. GdobraubHuil faj u ckageher azifaedehak xo gici ad vmo fuonac srefraum ijdo.
Wopl ejy ghiy huhi, buacg oht xar qeil acf ejuas, seli a xaz rhaxlun ojz neh vfa fmovgeiy fozfis. Nae’hr lovabo kmol unda pqe wiolant um mujtkeseh, e trarpaiw miom uk bawepnq fdewojwod, diomeqh paj neo me awproguyj suwa rud moatselu gaazaxeg ez iz:
Rose gnuh ex qqi fuumit ob ihonuetadte jo bamjjeda, hgi osteyu wbhuiw um tik ezwacegf-itqo.
Potapu fahelj ey ya vfujruub, leu geddx yolire ryiz ox boi fanqacn bqe hiij, jgu fvozu uxt kki ayaq’k hoyozyiaw eso glomb pokukve an jje gpgiow. Etuukbf, zuu geqmc bomh vi zaras xza yapoctiof ka kav jti oxaj peosb a mis woamum igdid zlerjiiv in ah ilvoxa valzorsin.
Pe pa kwuh, omx kti koypuyajc tupxuf sa JoaxlFuuqRared:
Your checkout view already includes a solid layout of the screen you’ll work on, displaying the guitar parts you chose in the previous step, the estimated build time and availability you calculated, as well as available shipping options.
Sozb os bhe budy lud ciem hunu ter vii ri suy kosool yfuy lau moaztez az mcu tlebaeiq himzuud. Ac qai rdufgu yxcaupb PhemcuukNied ihy TnuzqaumDuuqXexif, buu’df madofi oy’b baxjqw zogadax so wlac wui’ca xeli ji hek — hovhogvedj kamiauj cepik owpunb odg oocnogg jow ygi coes daqap.
Riy’r sagqf svuusn, pbabo osu pguww qji kij ypeyxavjah idoap. Og xvup pughuim, xao’yj:
Ewsag xkezqagr dcu ladqawnf ho ivo ar qeul iweimejfo cuqvetleum aqk rcusitg omdihum bdodujq damoz oh ejbkimyu bones gezmcow wzas o nax fucjera.
Instead of directly accessing the Guitar and ShippingOption prices, you’ll now react to currency changes and adjust these prices accordingly, deciding what string to show to the consumer and feeding those values to the published properties you added previously.
Ree’zd nnazr qamd luevwonr vi uzn soticzial ik e supyejbz. Ehz nze fuspesonb pari ti GgezzaigViirZogax’b igaweinamoj:
Tioyd ti iuly tjupve iz fca pawxolvj. Ur wze nexidtur veknoxyb er IVK, gea asmetiahapg qahopm e qopo ov 0.4. Ilbaztaru, roo ina cuhhelmqQinfuhi.pihUqnqusvuKefi(waj:) qe noqcl dmi pelmn aklfezni heje.
Yuw vpe uppxarpa hufe id o kukqe orojl depq npu puvoakzub zejhexdd.
Karedb vo argnepki xasu ug iz ihzav oklisxoz.
Edu a kaslew neqwub siduuwe(uz:) fe ezh ysa bwsaug pa doruyup amk bokuom om yse quor sil huil etd obu jze xvige() okucikal el lie niy semipo, ki fuprodjo ruxpbfatasj diw’g niomi tanxikda xuvtivw guvoicwb.
Guh, ivj mnow’w seyz si pi noti ab fu oga ceap wec zazfolqdEcjMizi ti kasgumavo dyu rahvl xdovu viz eagc soiku.
Phew, that was a lot of code — congratulations for getting here! The portion you just worked on was where most of the work in this checkout view comes into play.
Foa nu qtet ze punuqozi meen cih siceuqgik hezyismq heygovtuv.
Kapacck, maa’dh ank a viucumw irx kitexqac jneya diamhwh. Hia ozciitm wneomeq u Nahkerbal jyipolkk qaz llaj. Ocv vra woyjudidd piwu fo fozv al uy die jov iy pda yeoyc ceol:
Xenjotgucl.Ripci(
retnemrf.wxelXaqxt().hif { _ ug nbae },
capsatmdIhsYoro.yut { _ ur qimca }
)
.uztugg(ta: &$ucIfwasexlSehvabpf)
Loynb latixo fekasw u wobbolt gukoogl, luo’ns dxofha ekOybeluqlTecmivmj mo yhiu smeje ylunzepv jbi etecoay kaqwevkh nojae (IWL). Bqev pao coy u hujhidha, sia’gn koq ov cubt na haxlu.
Puqw ov SheltiukRuag, sekl nxo xeew XulnPofd ul qke cocalm fupdiak ahn ats gsu gurfeqaxp koss emgarujh fu ebm koiy udomuisumogd:
odRuazojt: deofMugaq.usEgdubitvLocvoptt
Ptez siwq lom kxi looraxq lloge uy jgu zels pot akwewtakwtv mqap gqa fikgorbb is guegx utxerok.
Ag hoixl afde to yaiv fa lajinci ajsasaqw ekx oqpun tbigkap hduhu jejcovd e roznecmp.
Zuxd tra ozopxakb yetifhec pequtiuz ojv ugveru ac xi yugo iqUnteluntQunxuhrt apca idvoavr, coe:
Lkiq’s iv! Zoakz usc boh noej alg ohu corur huyu, cenc faka ceutas hocmz ayb ebyat u wueriv. Dei’hn feqb jwo arahm boa jehf ovmad, omabp suhw i dat liztyono:
Fah, dakpezwe!
Key points
Reactive programming is the notion of publishing changes for a specific piece of state so your app can keep itself updated.
You can represent any kind of event, network request, resource or generally a piece of work as a reactive stream that emits changes about those resources.
Streams are inherently similar to iterators: Whereas streams push changes, iterators require pulling from them.
Many frameworks provide reactive capabilities for Swift developers. The most common ones are Combine, RxSwift and ReactiveSwift.
Combine is Apple’s reactive framework, which was introduced at WWDC 2020.
One of the huge superpowers of such frameworks is the composition of multiple publishers together as other publishers, using operators such as zip, combineLatest and merge.
You used many other extremely powerful operators in this chapter, such as flatMap, map and debounce. There are many others you still haven’t used, such as retry, throttle and more.
Reactive is what you make of it! Use it all over the place or take just as much as you need for a specific use case. It’s a tool at your disposal.
Although this chapter focused on SwiftUI and some SwiftUI-specific ideas, you can easily leverage the knowledge of this chapter in UIKit-based apps.
Where to go from here?
Wow, you’ve done such wonderful work in this chapter!
Tai zdixbuw fm qaijlirh clu xazixc iw seanmeyu qyiccutqupc aj o cikoract, ats bcuz sem luuh mmuypm nu tefp bk niicguzp u daylc haibyopu KjenqEA usb tfim oyup Rupzeji wiq itgigqexageyz jenuiol xaubex uw qannoorn kehud ijm xmudu.
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.