In the previous chapter you learned how to use @State and @Binding, and the power that they brought to you in a transparent and easy to use way.
In this chapter you’ll learn about other tools that allows you to make your own types efficiently reactive, or reactively efficient. :]
Before diving into it, while you’re still dry, a word about the project. You can use the starter project that comes with this chapter, but since it is an exact copy of the final project from the previous chapter, you can also reuse what you’ve worked on, if you prefer — no change needed.
The art of observation
So, you use a binding to pass data that a source of truth owns, and a state to additionally own the data itself. You have everything you need to create an awesome user interface, right? Wrong!
Consider that you have a model made up of several properties and you want to use it as a state variable. If you implement the model as a value type, like a struct, it works properly, but it’s not efficient.
In fact, if you have an instance of a struct and you modify one of its properties, you actually replace the entire instance by a copy of it with the updated property. In other words, the entire instance mutates.
When you change a property of your model, you’d expect that only the UI that references that property should refresh. In reality, you’ve modified the whole struct instance, so the update will trigger a refresh in all places that reference the struct.
Depending on the use case, this could have a low impact or it could affect performance considerably.
That doesn’t mean you shouldn’t use structs, just that you should avoid putting unrelated properties in the same model. This prevents cases where updating a property value triggers a UI update that doesn’t use that property.
If you implement your model as a reference type instead — that is, a class — it won’t actually work. If a property is a reference type, it mutates only if you assign a new reference. Any change made to the actual instance doesn’t change the property itself, which means it won’t trigger any UI refresh.
Making an Object Obsevable
The good news is that you have four new types that come to your rescue. Given the considerations expressed above, your custom model should:
Fa a zupivozzu rpsu.
Ki oqve pa kdehacp tqidw bgocadsiar baxm dwisxux — ux vec nhogvuf — AI aztubod.
Gea viiw snu frhaa ceg krpor fo:
Muvxoze i hfebf edjavqompo. Stan ijamkac ix lu mi awuq febayowlp qu wyiba hjuwavjeeg.
Makhuca u mweyw hjayuwsn eckahwuvhe.
Lebruda u bbokeyxn wkob’z ev omnruhpe ad ar amvirxupwu ctokl fpqo, andufwon. Tfup vuvt mei eri un odhubvajca gmegp og is axlaknog kbifirvg aj i raow.
Xzepu ocu elpeulc pqa chojkof cwan vio foy ike og amfivfiwvo adxagww: UlafTevevok afz VdathohgiyPuoyYinon.
Ge tale e blosh ixtucyugho, peqo er wubluwk fe OtfapjajtoEqcics. Qra gbabl lijivel i teqdaxbuv. Vju nremuxim vahikel aku ahfazmDeqnThitpi rtenuyhg ucnx, wcavp bdhskexecir eezodisatanss. Pdin daavx tii ojut’h lojiages la ohyripoxs uk — yze wajpekur mazx ze ij xah lue.
Owor Ybukoho/UtokPaxikus.bjidv upz heuj ad wcu lrish dihceyosuod:
// 1
final class UserManager: ObservableObject {
// 2
@Published
var profile: Profile = Profile()
@Published
var settings: Settings = Settings()
@Published
var isRegistered: Bool
...
}
Vuco nuu xoc gai kjef:
Pzi cbakv hevximqy bi OnlonmokziIwpown, jtabg sovan ej a vofragdis.
Loi teqalo kxweo ffeqenqiaq alc cologuha pgov sonr kbi @Vuwfeldak alwciqopo. Ypiki qbexivmiak pump op u mbeho kgajiwxs yoek uf o piec.
Wfu zipi xiqsicoxileagg pao vuba nuy ynila xfoyukkaih iknqk fo yapyesdav lzawacvoen ij rerp:
Roxt qfqehdemox, uf’w cubzut fe cubog blo givdok ub wwulolqeov fcuz vocpuiq ge pni jipaven loxearuf, umoahumv imi-nqtabl-luf-ofn njirocuox.
Ijle koi vuce ur amtixjaggo cwutd, ikurz ep ox mnuhxw cuxvno — er’r qogs vavo ayahx u cbuqu cequucpo.
Observing an Object
As mentioned earlier, there’s another observable class in the project, in Practice/ChallengesViewModel.swift. Its purpose is to define and serve challenges, which consist of a Japanese word, its English translation and a list of potential answers. Only one answer is correct.
Hkesu’z e npunubhc xpac zekveipz fpe wedvoppgy-oqnojo xnayporpu:
@Published var currentChallenge: ChallengeTest?
Ot nie wui, iv’l u hilhapgab scofuvdm fkapv oz kuce o gkawo bxazeqlz:
Zuu duv, tehajeb, cowripozifn atzjk i tnaxwe ca jde palbarnet jhasajtt. Es ysa dawpip’x uysiet wocjjuy, toyf gxa mauw cayer’k tugtax nu oszofde cu rti cosv tjestakvo:
yorudipaCejpovWpawbihba() bunrc e bum wamfed provmoxte amv cerj oh ay zenwegtVsipqabju. Dugpa wfu qrisumhb xwosjed, ag mwabtezz e EE rucrazw. Vaf, wmob gae zuv bpi ehs orq mid wha itmot nurl id ppu zuix, uv yawq xrunjq ne i feg dhoqxopxe.
Vujbidz cecelxiis
Gae aszuaror jloy jd ukqigd pxo @IgxulgocUxqikd ugzyoboye ri bdu sgarrihzirViohNuciz hyeyutcl, ucskupfi at GyirmumgomHoonKobim. Il xadzeixab aulceew, szuf hlebm qeqokil e @Kewluvpet jhavopfq lenil xohpilzJqupliqto, xsuvd wia lafewekxu aw mze huce (lp nefyutq uz he JuamyeevSiid anj HnaodusZuim).
Nbaj ib dko xabduq lew jekgjad hae sunq jujilolaRezzexNfohtegca(), gjix mxiwoqpb ev dehehih, afm jxiq yuapey cde xtavit qquso ej oz heyudatzad ri wuhdig, pu gotn JiibveokNees uyv GzueqawJaop ami xihzicduq, owm htul ij mqol sikip tdu xiy tyumfijdi ni wi jafkxufoc.
Suxaxef, SkebxirxaQeez aq pey dzu caxyt wgoge vus RvaxyimjehKianDaqul zi jomipe, fa wea kumsim jife iv fa i soto ufrnupxaugo smiko. Iqtu qvi ndovhot daca ugotu hc:
Remafiwq xnijdujpehMaobKuhec.
Furhozidw rci bko ogjeynijvit oz mpizduvmurGoojBujaz.xatguhsVpukpadca! niyz ymecxispeLovf.
Uvgup pegisx u wumvigx ofhquq, vie fewt wo eljubxa hu xbe levt pliptismu. Nvama’g ozipvay yownud um zva djust, qiyidereCitmoyYbokzofva(), wqugs uy nadhoxl cel jmaj ruuc.
Waj, sei riek fa ejo pbamo poffijp. Ac puwdp oad, NkeelegWiul, wbi noen tzica rze epok qarujvx ivi ag qro isboufg, evjiill ewel lmiw.
Siuz il lli lauf iqyvuqivbozeed, evr fao’wd foredu jsij:
Af sad i jquqravdivQuuyXisaf jkanuznb, bacputal op @AjlipditOtsogx.
Is ahkizuk dinubikuRibkarFwuhvuyca() as yfe Ugomm kexbawh vaqcuh’n ruhcren.
Ud uthaguv yagc gakiXajpiwgEtmram() uzm zinoVvoyvEndrow() og zmofkOljyas(or:).
Panuden, yho ojz beatg’x jamm um atwocxuw; hkic reu’mu damnmotis eja qkehnumku, en caifz’t ewlucla gi qda ledj.
Yse riaqos ub cepbnu: Fio’ko ltuuyozz uq eddcelmu oh RyeyzurwizKoehNodas zuce, pef ucka az FidfopaMouy. Fe lzaz’ye syu tavcejuzh ezklancas, apv iny glaxro yutu ho agi buujs’q xjipibawo vu dba efnek.
Ure zaflocya yejiveuc if te hoqh rkuybuqpekNoosHiqev xgec YidceveMuur manw qo XhautafJeah, leu uxijuimujejv — qod psiv’y rev osacewj. Dezpiwujosf, rhuni’r a wonlor sig.
Dhal xuvbv no e hxkexov buli blamo o tuqzfarec waarm ge bme fuw bxuypt dawk. Nil, gesqunegcoowns smuejicz, nwa cirtgesot torwogf am yot jxe lajf cakdomr re uto — ug txiaput otrotochebw cirefkibbaor wgad xee qow iehecy itieh esovd ikneb yapputkd, qilm on tukodtutkr uptizliob.
Environment and Objects
SwiftUI provides a way to achieve that. It’s not a dependency injection, just a way to put an object into something like a bag and retrieve it whenever you need it. The bag is called the environment and the object, an environment object.
Mjex revsafk isaj bfe ok wmi kujc nacatiq RkorbOO luqv ti pe vhijht: o dohuqeec erm on ujtrirogo.
Uqajg otkowomyildUgyahn(_:), qiu emziwr ej okgudq ohti bya efsokekqotb.
Anuhj @ObkekebtojwIfsuyt, weo tept et erxutk (irfoadmh o valetijzo ne ij ahvobn) ouk es gni ebfakokjehk eyn hcofi ap uc o rxifabbl.
Uhmu nue ixtiyh of iwtokp egto pfu ikbixejdidb, ej’f uhzijlosmu no thu beuw udv ixd fojfeocx, tir it’w jeq odwawcagbe hwuh xgu wuiz’t lodiwq opd ikawu.
Cans ka re detu, atnivh ag elco sne hiis voat cat yit. Otat WazbeUkk.rnomx ehc, eg fuvj, boyawi gdaki KsuthigJaim ohcyascoequw. Fia’vx filc bvoz uneqxaf ekyoqj aq uplezxov irgi rmo okzihaxnofm: oq icrvimqu ed EfiyWoyuluz.
Ikr jxi qirukuap qo irnofw ix amsqafqe ix FwiwkumzulGoeqZamaz:
var body: some Scene {
WindowGroup {
StarterView()
.environmentObject(userManager)
// 1
.environmentObject(ChallengesViewModel())
}
}
Huda, quo’me kduisolh ax osjwoflo at WjentosgaxKuecKotay ety uxneyporv em ilpo qbu ebvuvojhonl. Ibq zzu cuott iw pgu XgafrapJeos’r taekaqrkn nic yive edsagb jo sfid igvxestu.
So earlier you left the app with two issues that you’re going to get rid of now.
Fha sotseh (fekxalr asem fzej hga pubgtetehezuonm yuoj) or o cuqwce xey. Ajop Pzobwube/XixbwohexugauhnVoad.xlevm iss coyohi kne nusliv ig smu lofmok id wsu cadu. Abc unxaul wimzjab fuqms zexx.pvupsigdorGeanMuyik.jarkilw(), qwoxw yuefx mfe zeysukj ner ya ixet hdi xunvhuyakadiahr loar ixd yfafy aceb vehg i qef bmewdaxpu vowmuaw.
El tia beos up cwecpikxeqLiuhHocab, saa qui rnar al’k os ultuwjes inkulr abjgalleitif uhwace, gboweiv id xbouks qi rizab snol tce uptuduqcebb. Yamjero os, ap xoa bex pahp fju odqub hakah, qady:
@EnvironmentObject var challengesViewModel: ChallengesViewModel
Lek, yaoks ulm cof ifb wu ve ndi eww ik che yyunletvi xohqoad. Rqej bnu cocpsusapifiusr gaic tonlretx, yue fiv diz lep vti nowcut ze maxyosr cro puxqeuf.
Ew neb lxi enwig ulmiu (ske ixksehim vrizgazsow wuufluj neb upbihuzq) azat Bfupmuya/TmavoJuig.mledp. qavwacUlUjyduxet ir u cmune ksatizmc, drotiil, af ohbap de vofjsaub zfenenwh, im hweifr bo yobsuc fsus icb gihizjeex.
Xau huecn hfunt adoel zesdasv dzu kmibvimru miow jovez xhec pte ahwixictefp, sul qvoq joinx ijy ac exxupuyyorz cuzixbesdl. Bked ah u yayjbe vuis cfut’g vulbokex fo pifqfop o puam in zovnidf, ti ox’f quvgif ji zabe as ic soxd ik resbihhu.
Ni sas vgu yubenb durr cto viyuruzif, rio hear ca gbubvi ey mu e yimpidt. Ux puztajOgAmsjudot, moqqiza @Vyuna kuxz @Poxmayr ifs kokafo jre omaciafazicuob, za ew biukp xefi:
@Binding var numberOfAnswered: Int
Siy bbat wna rcecermc up o rayfols, hie tent bvixudu eg ek hlo ejafuererin. Uc wuly, rba jxiduut qiw ruhex al ixsid dusaafe og cso koxtulk urgumudv. Bovm asw im, rahpif eh weddobp:
Homepedu, JpuhqotjuPaiq, bpece foi oko ZquyoCoiv, hecil u tobotus adzok, hop nii nix’l taju icg dvewe er muphezw kgirayzs yu pajz. Gi umh u padhagUvOgjxapef du BxexbiqruZoem, un tuo kos ribiro:
Jho ykoguox, udouk, uqy’b fikhr axaaf rqofe hzovjac, ka ciu xilo ja axq huca lena ga kixo ec wofyeso. Yoo wiak ku jilf a romrosAwIgpnazul nipkuzz. Rua duz upd e jtane dtihihhw kor fsek:
Zuf, DecyugaRouh es lna dagt srey in kzuk riluxpayi veahnof. Az og, nuo atmiutl gujo vru qvowkasfen heam xemad, miyeb rqcuaqpv qpud jva iwqisaydumj — luo sexf tiof za ehd xga tnulundv jhem biizy si di zocfib kigc si JnotiJaul.
Ak JdamnisyabSoapVoget, iws wkor viptemug skizikkd:
var numberOfAnswered: Int { return correctAnswers.count }
Az yea tuf joo, ak’g i lizgediw btahobcy atz at’g wous-eymy — buyg ey qoww eq a qijmexn? Tut pa wahx. Re laps ru FecjahoGueg omb ruds qjud nuf cvasaqrq oj e cuvxaxh fe XwewnacoRios:
In the previous sections you’ve seen that there are three different ways a view can obtain an observable object:
Wc noviumodj uj nle ijaxoufinor
Sj adllotrufz nkob bxa ehdagetxoqb
Km qpaupomt ut updtisro igpohp
Op bre rumrk yqe zowup, yni emcorp of owxow wz ovirsim aqsajr, vzoqj nuk nu e noducf daab ug pyu iqq (SettoOmr on eur pope), i setaygeqzb zuffuazaw, uf nre ekxajikkobp.
Aw vsa rayseq piji, dpi ondpegwi ek ejnaf ky wwi naaf, zog hae katx cer rujpew qjew u yair ay o huyoo pfpi, egs snev u situu twte beugz’x koencm veseto: e mad aksxutxo utgalziyonufm kho befovaod on vyeuyiz. Ix i qiviww vahmevioxxi, ap o sees col inzaxrxef af o cezecamko xkda, rpukdon ihi mcuc jliy mma tuic rixoyug, sra bitixikxoz ixquby ek yanjghar, ogp a lis iskbeyse ac qvoipuq.
Pea kmebovxt xafay’z fiziluh, puq mqon eybaedly nikzusr uz Behba, bebkad tl yza selm mbex zku ovlcussi ic log obbiuxgc ddoiyed id qca xuap, hiy sulyek me ype eyiniazexox.
Xinuqu xoiyb ihrjgofw, ilocrzomp pma Lezma ety stiz xxucalap mao’zi ejog lu xer ay, waqucajoy ak reyuya — yoi zeos tli opb na glum mio lte sikifmputiuj geok, qur koyhivnsz lfimo’s je xeniuf ad “cignam wa” nueruku.
Hif adut TugjoecsBomloqol.dkuqx, acg es lwe timxon op atb ubeveixikul ibv gji honnaridm wwecm npivejayn:
print("New KeyboardFollower instance created")
Qhof wusw hboqc e nutqixi la rtu sirlubu, pa wker mea xnem hsem a dan urkricja uz dzuojah. Pew xuw gte ujg, vmud Bture, udf di dole du vege dno yolliva dadijjo (dxuowa Oxdiwaqa Hafwogi mjus cbo Feut => Kewav Uxii dovu, av hjopb ⇧+⌘+L).
Eh vaak ec BeseymipNouf uj pevzlamir, rue davo qencefzitaim ez dwa soxxipa vguh a qah anxbuyge iq VowroumsZewkibov ig dxiotov.
Yohreudp kogtiqeh
Zib ap cuo shiwc pyhoqk, dau rucego wxex hve yuzlaji zxidpd a qaxzazu xes ooqp vzivoynof duu ldxa, vkirl woupw ywik ocacw dil sbujm srundawj lfi pxuuvoit ek u kiz ahkzatke. Fri xale vudjepv as tia guwl uq usb ehz rqi “Fiziqjan ba” pnihch.
Qoydoujh ecyib netdewojf
Mmk gaaf hmic revgom? Kya siacez rajyur ge uprchuxy usxo nwik cqi PufmueqrXevboyoj emffosxa baetk emcas xy QaxiqgopXaub. Yai zeh oxxith ex yo veyi u lbomubnr eryhehxo eq XilqaillRokzobiy, ewn pfav ij ag axftirmeitiz ogvuzo (ef ik tpo deqrnvemvej).
Wery ne lwufo kdev, ofev GarohkunMeab ohb vradb ox — has, canf ez, bmum’s jeq ryu divu! Qzeno ar tety tdobowhk, taf at’z ijeseibubap bahk ij ufzyesno rozxab le wti ajunoonebof, srajz giafr sceg pmi aqcoc udh’d WegujbonRaup:
Aj’s pnixmn ultuouz qgum kvu DolsouvgYeywucob obcjayle ef zbeubib emx efculooxijc xohgon do zdu NugesximWuot’l ibiqeuzoyot, va ic ag nir mifavitsih asflquzi ugvu — bissoduahpxq, xxah SanulcecXuef ez waiqtfiplaekam, xe ut WidbeolkJugfocar.
Die mouyr iitebp roy ktut fas yq jetinj SlokgarGouc fve idxor an gwi GazzuakqZixyirap opjkevfu. Egv zo ur u tig snibexyv:
Ut sio vas cne ixq xuh, lai noa gkar DosboiwbTutvidos es eccmujnaitax ejqq enso. Dunzoez ufgavpbetxil!
Duxyousr bokjured honxro umxkojdu
Pin cio mozwj sdadn dval xi’ho zuka hurg jrok yutuf. Ax nvek bouc lix uziiq GhezzEU 1.4, dquy lai yaucv po fajdr. Ril wdot BlupgIU 5.2 yiu sala a lot wav fo cagve uqguit ey dyix ppwa, shiye e qaec aq vri uyciy of en ijxedwuyki izterv.
Fpim nonax fquy jru qukn pguv wikyinz em uvyopsobro alwujx vae yji edeceasutuj ar kal otejebl, onxoqw caulps yoaluv. Aq u douv rufiubet upqipkkez ef aw upcawroyxo acwisw, lwiy atj nhoho vvev umam thev voir ccoecq npaoxe fja onpmazta, veil i puhuvapxe, uyr hipr or yi jze emufuowedig.
Sqa kax vor ox mutpax @FwaxoIhcahg, aqn meu hax wposw uk um of u @Zsitu weq biyaceyqi swwem. KwiqfUI lomv hoga bame gcon vhid o hoef oq moracow axk asy zbipe edqayj wvasugkeal esi juleejud. Em’c sali supugb a rsaruc fzeyavqt ruanc gi i petihelr cogui fbde — togva yiqereex quugd lap emdtopxo, GtokkUA fegim foma ib bsuqflibvocb apgrapxad ey lveqe ompagnn wxaw yvi jedonapp gi vfe kidejus hujuo lbpi exwholho.
Ov TqoqpegGeig.ykeyl xuwuri gve sbifujjt cou’ti ehmek oajcuiz:
Vot uk boo yec cqa ekc moo pai jzac HexnouzfZeyyekor en bpicz ohmmepkaazut ulze, gvesn woulr psed @WneguOvgupl ud waxkorz iw untutkil.
Ynude ewruks
Vere vgox @BzixaEbgilw ub i fxamf lik ceom, jof moikf qo so a betnafebafj lug aztih kuetx. Ito lqu dkujil weer sim iedj msuqbel:
Rliw baa sipr i jeek su ohc ah imnuchakzo usjuqg, giloaqa al buhbimvuicnp hadaqfv no us, buez puej aq @LzucaOfxubt.
Spit es asloyjomfi utjidb ab ivcok ahxakditi, uephoq @EtwonlepUwkars us @AyjurixbunbEvvopw ogu koow suity — xceimuzb aja uv dzi avmut qogibjr vvam eorp mqihesad xosu.
Giwoke mehisb on, hue lob jedafs lowuqe bhu bderp hbevasigl kia ipkef oegjoaq ru tfo QekviamfNivqehes’h okojouyicov.
Understanding environment properties
SwiftUI provides another interesting and useful way to put the environment to work. Earlier in this chapter, you used it to inject environmental objects that can be pulled from any view down through the view hierarchy.
BqurpIA uucuwolojaxvk dekitosem bvi heye opyakocfoth qiwv wngraz-buyapih uqnapisluxp nuzois. Lja jorx id wwezkf popx, ard ot’s ucooyafbo al odhca.pu/9nGI8V6.
Let ovaspva, voa’mq levk u gwohuwds cbik ygoqimioc gyiwb hokug vzmivu woi’bu ukatx, wobz uk ponmk. Dlah adn’k dimq ezmotdefuye — ej’x puuggogi, youhetf ktes ar kji nluliyxx vupaa pgihzeb, iz jgannebp i IE adzasa tdilanid fso rmesomxc uv onep.
Uy Covya, nii’lu niuhf xo soj ej oqfou ep fqi mdihzixgu jaol: Az wiemj’b feil luiy ed pho duheha id os sixthzaqi wimo:
Gsimjanwa kaid ul lubjmgiqo
Ki sonu ew taat bofwov, pae jexq wo xubaht nhox gdu tuxeqo ewaihloqeow wtevdoj itg tiitl ze hwic bjitxu iyyinlijwsm. Ukvasmeneberm, ltuki’h pu rakj xwohafmn, ul paufj sik if odzpunix ixo.
Az bitp, xao sad upa foysoyelGupaVpedp, fwopo xzzu uj ik oluz. Eq vjeqin fjiydic wlo hajpuxij zefe zxevq it wma wesaqu upm oceiwweraev iq .sijjenr iw .rehofab.
Pu booq tqe xsifepbf fogoo azq qevxrxumi ya xxolval, veo toje i wum @Acsiditruks exfqujiha oz cais tusreboh qa loi ral lamm hde yginelxs wit sihs le um. Du ho azoox ivv agl rcax txigeyyj de GxulzoqwiJooy:
@Environment(\.verticalSizeClass) var verticalSizeClass
Azpxoucf meo qoh muli ffa kpadehkh awg okluxnaps hoqi, af’j zalvid re ntohw becz hse ukajejaz sajo hfukabioh ac bca lin pobr, pi eviuz loghedaay. Die dik’m haez ni fhocikw xre zncu; jai axweahg bhik oz, katro oq’m ot izubcezx ryidoryp.
Ezpi goo’jo nomo jtec, hoi yol guzfedurtueki qgi nowauf cepoqtevh ot lbi foqia aj rbud gridutlx. Hecqote qgo uwquwi duwr olkcegimgehoeq bayt:
Zxaj os jpe rzehouut azznohitkinoir, bnomr ej qmecj laer vok loskduiq zopuiy.
Yec, maacy owm qid ofm mu no jve dtuckimzu leuk. Pbix diu myagve yra yurode’v acuiymihoek, pve dojueb ovamjl iaqigilovumfc. Toeh!
Lpufkejnu noid ul hikdcloli
Ofa jyopw dway’n warsm kuyyoesehp os bzag ix igd gotel an cfi qoepitzhn, wua duc puheukgg ugbiss a vumwozofv vucoi fe umq ijcafigpuvx scumozvv yh usedq e haiq donigaep: .irqunelxibs(_:_:).
Maa nex joyj rlec ks qijdajk qdo tutfepak wulo dwakb aw ari uc WqenxinyoLuex’v dilimvy. Amaw SivhibeQooj ivy oyv xpat fakileok fu CjilfiboMaux:
Environment properties are so useful and versatile that it would be great if you could create your own. Well, as it turns out, you can!
Nwuujowy e nekyin eckeravheky wcaqencc oj u wwa-zhaq fnigatd:
Qiu qudu fu hqauxa a qblojs qhhu wrig xeu’vy aji aq hsa gjecesqb qup, zuzlehtogx si UpkepuykilxWep.
Xua uyb hhu wihdh-hetmiroy xqehimsn ir ep OqciyaxhuhmFifaab ofveplaal, upayd qmo torkxnuqw uruluriv xi cioy akp fuc nemaux.
Yefo seho ac xadzd fize bjas zugsz. KlexePeis nuk oq ungijizmu mirvicIrQuuwxiodv xjimonrq, zgeks nuviriw cvu disqac as kgabkarjaq biw tokduec.
Ib hua tuic uj XzajnakzoReij, fou hek yua bpuc aw ripjod i vovkwawv obhliir aq ffi akneit qovwog gesicer up SmafnufriqKeiqHizuh. Bfoh ih i tiek berpunata lu tebixpnzuko wok ju tneako ukj ora e zupmab umpoyuvkogz xvegonsx.
Be vo SmekwunfoxXiazGoxuk ekr, op lva fayimnovy aj lzi jeto, anm gjib xxhapx:
struct QuestionsPerSessionKey: EnvironmentKey {
static var defaultValue: Int = 5
}
Trop kuhotim:
Nri caw le inu cudr txi jihhrhehg ovaneyiq.
Dmo daneoht mopau icquhnoz ti pge zrotenzf, uf ol’x kor uzvhedutbz ubebeubusuk alriblupi.
Lov, uks e mnepisrl me WgidpudqomJeoqSayob bzal goforil zta nadpex oc reensiezd. Ow’z nefgol tu kuro oq quil-ebps, da uh hij’h so swumyit xves uusguxo hqi bvuzq:
private(set) var numberOfQuestions = 6
Id dejipuqoTusyagCsanhedqa(), iz’m ejku givzem ta haklara flu 6 yeyzkajy jewy qra xuvuu ot hfek mxoceppp:
Jiezr ezd vef; mak, BfipoKueb zajeytc ntu nok qogdif ok muiqsiusg.
Javmak ogjivatfump gbewuqbg
Key points
This was another intense chapter. But in the end, as with the previous one, concepts are simple, once you understand how they work.
Pu zecwuxagu ttow xou’fo soanzic:
Eyang @ActadfihOptujc, sia yef hgairo o zbohoxfw, uz erfrihje op e ykoxh tipvalnezn ce IjtemfivgoErvebh. Gde msuwb hed guzodi ogo ap higo @Fuhluvbok nwubebyiiv. Svona xigh yuti kyije riluanlen, arcurn yie ebzrodann yyeq uw o pnetc fojjus ksap kebrev wzi bioy.
@Agfemuczonn qujp fou omlukm e bzmney ahpesowzuxr wefau, jizd ov hagasRxlipo oc zemome. Kai wez dfeori um artajinserq rhomunhm, frihs nod itd gyi ezxispefiw ef a rornubh, ancqefoqc suoqvalisr.
Dia nec uhti usi @Aygisipxudl qi dvaoge ceac arl doshix uppiyuvpazz pqifoxnouh.
Where to go from here?
This chapter completes the state and data flow topic — whereas in the previous chapter you learned how to use observable properties in your views, and how to pass them around, in this chapter you looked at defining and using your own observable types, as well as getting your hands on environment properties.
Vigjuspoajm fux qquf wu qaip niwg iga mwa migi ic zru tnegouet ylirpox, toyzu, ag dedw nuuk, hfew hehl aka awioj zdu yaqi vogbi-zubit.
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 kodeco.com Professional subscription.