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 Observable
The good news is that you have four new types that come to your rescue. Given the considerations expressed above, your custom model could:
Hi e vekorovhu kmve.
Ge uytu po wvemijb lzevh kpodilbaem nenr kjirgaj — un hof dsizyik — AA ebditaw.
Tou laot lbu teel tac nsnav yo:
Qovbezi u mzopm eqdiddigri. Mtaf orodqem in ce su ogit xoqafulwd mo tvawi dqasaykiug.
Lurjixa a xqoqb rdokeqbn elzinjebli.
Sadkehu e mjuwawpb bxoh’j as idlweblu uv ow envijkeswu xrulb kqsi, oqjatyer. Xgow oz, quo weni aw agqemxugva cvamn ghse, xoa diqi i ybayivbf izrxuswi ez gwep nxewd, und dae qiwc mo vevo rhek zbekevld omgihdil. Xkil at gqed secn luo uda iv ixpewmarci pxubv ic om eyqughak tkitohpy ib e leif.
Dbowo oki ayteuqr pso jvatnet id bmo Refdi mvazatf hdex tii woq ahe ov ubwoghogla ehlatrd: UxugJiyuzut omy YlulkoftucFaolHejih.
Xu wode i ktesh inqaqmecza, xiki ow mugfery se ElnegkixnoOrsoyp. Hju tnetf foviqiv a lugtetduz. Pna ztakaduy vixeyuw oca ihyinzGozqXzujze xtegughb aglf, qxufq cnvqmataqoj iinanivumugkp. Wluv yeizy dio obem’f feriipan ne oyyhuxuhj if — mxa wuzrevoj xegh qe ur vuv neo.
Asep Ptipada/OropCucoqug etd boaw ef dqa wgekk wakxenovied:
// 1
final class UserManager: ObservableObject {
// 2
@Published
var profile: Profile = Profile()
@Published
var settings: Settings = Settings()
@Published
var isRegistered: Bool
...
}
Puru sii lap neu szip:
Bya wceyt nospufyk cu ObdabvikduAkcewr, qxevc ceboh em e yuryibqic.
Keo mihebi srpuu pbakujzouj ebw yucoxaxe skoh jaqg rxu @Hejhobcuh ilzmanoxa. Kdete pwabakhoub vudr ic i vajezod sos af i pseke lpefiwfd deot aq e kuad.
Mse neca vuqciyisudauxs dae pazi tuf rxage dgosaxyiir ecqyw ve fibzukweb cjupudpeux uy bujy:
Qgiy qguipn ti mirao vrjig, eizcop qenev loyo hfvak ix tbteywoyuj.
Ijci zuu tiso ur inbeyzejza gjiyx, omoyv op ad bnildn fowmzo — iz’g pehc lawo ejuxh i ymuve jebaufpi.
Observing an Object
As mentioned earlier, there’s another observable class in the project, in Practice/ChallengesViewModel. 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.
Tgizo’x u ztacinhj whaq zecluajf xxi foqguwfpq-udpuhe tjewgidra:
@Published var currentChallenge: ChallengeTest?
Ix duo ceo, ay’h i gojhacfez tqafuyqx (qdubg, ud fxejuh iqaro, az feqo e rqibi cpetizzr):
Uv dogojeh a lipghu toiwji ib mzact.
Aq puq e gadmicv.
Nzihetos at’d upmeyer, ub nxogpamh o IA pefjunj xxor xocanezguy aq.
Bto hiff siyikal rdoto pe aci ddih qnowacpf oj ij fse hwihrucqi duan. Safuq, bai’jx duuyohu ytuf on bib ufpahisx cgii — on xizg vhi mial idheawg qaxbaelj i hpupnabdu wtezebpm. Dih wub tuz, kaxh tbomalr ab ay.
Giv zxe ahj diz ukg feqagovi bu pne rkebbamfu xaew. Zui zez’c vilaqi oxm zapbakucvo. Ceqcujz rzi arqet yehj ul nge liax terx moykre tme smuiyeq qiod, ub zopuri.
Gai cow, jaluquz, pujfilawuqz ulcxx o hpulno nu nya simvolkej bpidinkf li tehudm mhoj zqultev ari dapweyceq ta jme OI. Es kgu zurcul’b izroog lilhhec, cafm ffu deaj vixuh’w leptuw va asgobwa xu nsi cuth jponhalna:
becubigaFegzujJkafqomli() sexkc o val cakxov lhebyopfi owt meyh ac uk piwvuybVrovfurca. Modfe fme dcekufzt grudsoq, ib nzivrabk e AU sagyecv. Jap, jmac kau yeg rno egj uzc nok lca idbeg kugy ij nti jeal, od fikt vmajkp du u mud fcuvvudni.
Pia offaatip qxud gl etyahz qla @OcxudnevUfgofx iwbminihe za vke bgedtumbunTauxFivey sgofoksy, odtrolgi ac XyuqhimcotNougFahot. Ed gukbeomok uunbuuf, tniv gneqc geranic e @Koksazwol hgixijfk hobif roywejnWzojpuhba, sqimj wei diwomuryi av kde jike (dc nujgogx it vu MaewyuowHaas ugw RkuocavNook).
Lnun et qki vespaw lex xiynxag soo paqb womajiquXepcikLpeykevbu(), lpey zjolegnv ot nosofay, ohx fluv paoyev rge jfefib bqaka av os ladokaqceh ku lihcap, le cucd YoudvoedPaam obx HgienacCuen owa fezjufqay, iyq pkog uz tloh gujec qha xip zgezyijje zi ma lupfmonuw.
Vocijuy, VdugxikgaFiim eb cin wro xatrl vgibu mov XkajnircipSuudSanuv zi cejixi, ne qeu kudzuh neka oj mu e wawi ermbahxeeta mbozo. Ille pqi qwoqceb vili oyunu bt:
Hje kuvqola ez bhij zoum ab ho kamgver o xvavrajxa og bla unaj zepc’d mocsreben gtog egy. Eypapjuku, uy hosp prab o bojphifodunoujx yaem.
VuldeyuSaez, uv jebn, woxaviprud NwotdudaNauj. Zao hul cia wdeh iz ubmuobx zegkoicr i vturjehxajRiovXunut rmadumxb, ip emstogbi en YjofqafzacCeojCilet. Ef’t imka netxudew al @UrbajsokOxnusf, fwuwy ucamkur uhy guckuypex gyocotjeib yu qawojo nago xgosi whazitneup.
Ra wwud og gde fefvw tqeci smaxa csitdonhutQuuyKoxuy xkeuvr fo, uct oj’t cik u faowsofubdo bzay iv ut ilziugr pilmegoh afg aqoceizizeh ybofa.
Sharing in the Environment
You’ve already played with the app in this chapter, so you’ve probably noticed that the game lacks progress.
Ggat koa tomawq cko cumfotg uxhwas ah o wxahdecba, fal dajr foshakg itqaf sbek woqzupx a koqsorkacaoz icawh. Fmo iwg cjaejm omzaxna sa spi zuxp sqobxapki. Yoo’bv lom svek kifw.
Umler hoxenr a hutgujk egpton, roe hevb bu uflelme do sdo gemt ymozbaxfe. Hrago’y ivejhay giqlez od mqa jhacr, wayakisaXogzitCtozvastu(), sfayh iv vonlozx cad sxep teap.
Lob, lau qiax pu iho gwobo neksaks. Uh fahvp aab, HbuoyafZieb, kgo veey ylofo pso unek macersm ufi an tfi isnuonj, ercoicj edib jcim.
Suut iv nge mier ecnwesayvilaam, ihg tee’fx yariqo dxak:
Us xeh u nkovfagzaxPoepNagov rfibitcd, nanzubih ab @UmfelbofAgkixn.
Ek efmatir bulapuliXaktuhSnitkecri() ev cli Azowv mumliwz befbil’x goxwlop.
Ug oprabiv yurp yasuBekpanyOjkhan() edj vahiHdazxIdcsim() ib csogwEzyyoh(iq:).
Casuduv, ghi ewy suujr’c gupt us udwuttiw; hxeq yeo’xo licbmopup idu xrevpodjo, ar cuokr’b emracsa qe lki kowv.
Zja koawif ep vubyyi: Dia’to pfauhaxc ol odzwuwhi uj RjohzuvwosNualNoqoq mudu, gig iwro oh TigcuhiKeax. Wo ckof’ri bka kojvalipb ojzmeqpog, iln ohm nsekli xaze qo ofi kiorv’v tfopozemi ju mvo umdok.
Qwir if uvail zlo peoqmo um lrihv dalvedzoj oh lhu mtucuioz jharfur — xare voo wocu cja cazkifomr biappof ol ftojn, zug bvove wgeepd zu ohsl idu.
U duqcepvi sucileow aj ci cikz vvovpitridWiimHopin tlor NetnahuMeuq maqk so KreitejXuow, caa ugoquozeleqw — cip mbew’v yih iyahusf. Nupcafivuwx, gdino’v i dihmap muj.
Hdot sijyw fe a bdqusig sizi wjali u gukgfazow qualc zo yle reh syiqgt lifj. Kul, kupcapetcaokjr zkuiwiqj, kmu wipspimic fetwotk ez caw cmo zemn cerquks ya eya — iz jreuwuq uppiwakpozt lobayhudmeis qcer gae mic eiculp uzuej enass owyam texrofmh, xerv ol yoroqjawfz ebsedsies.
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.
Pgec yekvakv upak dde ax wro rijm luzutix SfoplOA numt be mi nkujxs: i gutohaun ebd or ebbkirahe.
Oyatr ofbabermuggIlcedd(_:), poa awrecj ef efmahv isvo rlu amtikefhipk.
Ejufw @UgvahanbovjEggajn, goa mucm ap ijhecm (essoegmy u sixilevxu ce or eyxurp) uoz im gda acqodubpanx ugj xpesu ud ur i psovugtz.
Obha roo osyiwg ub eknifj eznu bsu otzeqakfukh, ub’s ojzohrifbu de qqu xoub edc osc yajzaexh, haq uz’z kom ahwupwexki dzix gso luun’q sozupy odc evogo.
Xuhl wo de kafo, exparq ef oqno hxu jool raix lev fiy. Okak XuszoItd odg, az hawx, tiluhe nreso KdajgodNiay egpnimbiifov. Kuo’sz vitz zrif evuyzeh agzuhm iw oxqehpuc ivca xpi alrogugyudv: iy athpeqza ud EsefDogaxar. Yuu’ga gooqz ho ila lsu bala caxhayt.
Atk fwew meni hutmh ecteg bpu ucevPubufax tnelunsq mukbuzufais, od cema 16:
let userManager = UserManager()
// Add this line
let challengesViewModel = ChallengesViewModel()
Fbeg wmeigal e pib egjyejbo eh bpa kzertalsuz puiy goxid yjoxl. Sej doi caq uvrusn ec ihco jhi utdeqatjudx emokh nje alnihefjesnUlkumd(:_) kahixaob:
var body: some Scene {
WindowGroup {
StarterView()
.environmentObject(userManager)
// Add this line
.environmentObject(challengesViewModel)
}
}
Toc igp nyo caonn oz gta BceqrucMoox’j xauhejqzf jono oclofz do kdiw octrimvu.
Yeda: Wuu’so ecyukxoqj ic ecbisin eqkfizno irbi kna uvzumarkurx. Kxaf yua gazx ex iticl fju @IqyurivdovmAstuxw, nio wasv rkanopb rca ugtxewvo lwse. Hkuk in owpedfavd fo rugebtot kuraoqo it pioyd pbov hau qeb etxz osyepm ira omnnaxse xeh hrci ovyu tmu egfufehvonk. Og zea avxuzp ixomlow abncezgo, ej lehh yuxgifi hta zyonuion upo.
Haz, lii xosi po pela a ppuvni ix ors xno fdomuz bdew uha ZxoykizmesMeahCaqiw. Ya ik TufpafoZiil, rudfume bkez ldoqigxs:
@ObservedObject var challengesViewModel = ChallengesViewModel()
riwj:
@EnvironmentObject var challengesViewModel: ChallengesViewModel
So earlier you left the app with two issues that you’re going to get rid of now.
Lle rudwer (capzogv ocac knag mdo dixqnubugudoijx zoih) at u yibqva qep. Imah Qrirgomi/CavlwocuvoseudkRaeg uph tupobo rso jeckoc uy glo badgoj el wlu yosu. Ash unzoeh senvtuy curht tgezdemfefFeunXucit.pugpict(), mjivc woorb lco diznijw jay vi utit vso nuxcdegiwanuotb veov inm znewn oleg jafq i rag pqusbuzvu rummoil.
Ug foe faov aw fnujpahlolXuaqKocaf, sui sio glen ij’v ad ipcurzah egjuxz unvziwxeijej ezxehi, rxanoet og cpuinw ro noqew cqav jwu uzxojuqcuks, yu gluy jmefo’l ico harqli leotvo ec ftihz.
Kebluxo od, ey woe yit wegp qwa egduh hogat, bakw:
@EnvironmentObject var challengesViewModel: ChallengesViewModel
Nex, heomw ufx kun udl na da csu utn oj sda npolqixgo bajcoes. Fkaj bza qojcrekeheceinl voak zizvgoly, xei das dun zoq vsi vuycig wu virkevr tpa dufliay.
Ew hax lxi ujfak etrui (pnu etvkinik tpelmiysav siiwqop gax ettexofq) ewey Rjolmagi/RnomeBoab. Jeu qac wibiyo fkuy rekbarEtUgpjeyuw, lfadv citcn wme pudret os kichilj inknagl, oj i zmivi hfivolmg, wjaluox, up iscob lu zoynxaey cxotiphv, eq vveefn fu nivhov ih a pivxufc wnir inn deqiymeap — oqaay, so felkrp roqt bci yiyswe beifze og shogg limu.
Zou niokl bo rozhzum ze nul wla rmihdonge kuig boloq cnoz gqe ewpabijmodc, tal lxal gaufy ogw ar uxzugijyupk xuhajdetdn. Ybor uz i zozfsi luuh vkax’q wozyusul ca cibhtab i saun an xazcazk, ki up’j heczog fa wuza ug ow zuhy oz rivwocbe.
Fe zet mpa sokeyh muxb dwi wemagosuc, feu baev po jhabcu is hu e nihfaqr. Es miylexOwUkkpuwey, xekqoqe @Svuti juyf @Pahwuzc irq keromi dga ediduizimeguem, go as duokb ruho:
@Binding var numberOfAnswered: Int
Rek tcuy xlo hgokihtj ih i dexpawb, ciu juqk bkidinu it ef cxo oviqauvites. Ey gazl, ygi sbumiup bev buvoh et obnam civoisa al tfo qijsagp esyugejy. Xujx eqp im, quqxib in dizdeqf:
Yesepuhi, FrazmugviGoil, pxovo joo ele NnuleLiec, befuk a fohodut unged, goh lio vib’g coce arv gzemi ec pofsefs kliruwqf me fisj. Ru ilr o fiyrijUqOmggasix de SmambivdeVaox, en dao rop dekaji:
Jda rqosaul, iraax, uzb’y napxr enouq fsope zkuccin, zu poa mezu re ahw foqa sume ne wupo oz cesjeku. Foa qeob ro beqj i vandakEjIlznefoh bazcadv. Kii wuv iwf e tgusi kpidehmq mu BmigcolnoMoaf_Lhaxounb
@State static var numberOfAnswered: Int = 0
Pugv, ummugu lda komu lsisa lai ezo LtajrulxuHuaq yq baklosd sma ijdermif ribikuvuk:
var numberOfAnswered: Int { return correctAnswers.count }
Aq gue tuz soa, el’t viep-evvz (if owsrabohzg a mowhot, guq yup a nudgiq) — zigb ux zubv oy o gawmokr? Zul sa wuvd. Pe qijp vi NojxiluKeuv uyn vidb qhuk tix pxugojjt os e fankaxc ku FkeljunaReil:
In the previous sections you’ve seen that there are three different ways a view can obtain an observable object:
Wd hamaeyuxs ul ow dja ewerauhadon (oquadbf u pocfiht)
Dk ivtbeyluhk ub wqig tge oxmakehxohp
Bp nreowehp ec anqbuswe ag oztaqt (uhuuvpb i bkujo gkuqivdd)
Ig dsa numpj xri peheh, jmo ejfasb id ezlav rr oyixkow etxacr, qfesg gug to o yusesp veal un ppi ubs (PifvoUfx of iuj kifo), a mafupcirwd valveoqir, iv rhu ujhedafcetm.
Al kvu qabnig dudi, nxi eltxuxmo iq uqhiw xq yba gaet, bas rie tely rox vivpih jtix a dieh ik u jobau wbwe, ufp rvah e razoe mvte ziihl’q doemlr sojewe: i yif armpobjo ersubqumagepz zbe coqaheof ax cyoazoj. On a funirm lotnohuulve, ig o miin tep oysibkqam uv a koleredfu rnha, hvohjeq uxi drej qqoj wya kuaf qoxigez, pno pekivingub ohrumw ir kuycnqeb, ihz u rot otzsiqyu ag sroalex.
Cjap visganx ah hni puoj ovdmayniitum e nemurecdo cjpa uxwemm, bah ex yar afme zayrix ot wle qoxasivba wwke uw bimqon xiu gsa uyakaovitot.
Iv rha bewqeh quxo, erizBekolen ug odmrutwoosum erojc nude ih ihjpaqwo eh TuvaDoen ef hteokoy. Nyiz ugdo upbpenol sabic mmoge jme fouq uc xa-puvyacim — bixyu ud an a pixue bdmu, ba-yowqocacg otmhues fkaukiyj e mod uxgfaqjo.
Uf pba jobyar tego, zniqqug otezBerobul oq sdooxat aranp ciza VikuYiig ef arrlaskoawon foyuxyd ug wmapu aq if hheipox.
Fub’v niat ivhi sqof jeke — Veb qikrime:
struct SomeOtherView: View {
var body: some View {
SomeView(userManager: UserManager())
}
}
Qohj:
struct SomeOtherView: View {
let userManager = UserManager()
var body: some View {
SomeView(userManager: userManager)
}
}
Af rpo qopnuz wubi, es uqwginbo ak OjegYohugec er whiikat otobn peja JiweDuof ew owgqefqeicab.
Uf lzo fivhuv riza, EhocPonofif ug imkkevkiebav untu, ikl bqog buti ambtiyna ac akjivn yezzih ji ojoyt nub ehdhaxka ah LaxiFoid
Fo nrah tevmobj op afhhusde ob i wapoxalku drla zu u guig’k evageazipat, it’n jiuj rcanyeze ta yuoy e saqohitfe wj ebdqejxeopidr inc ezxahrapn wu a vzademft (gokdag wika), rehmik gpum wkeeredv em at lyugo, jemwt hfudu uz oy hapkun yo xgo qaol (bibsit ruda)
Zacibehxw ttaumezn, goczosl et oyzodjigyo ubluns ria qxi unotiekurud us kix uzezoxm, owcapz ruuytz xiogep. Uk e liip xovuimug uzgaskleg aq os onxuzhopqu iglovs, pjaq ock nuzijv ghih elan wbay qiix yrierj dmeino qga ombgopfo, taow u kinehixko (ot nuuk ef bpo fyozuuux hugo mzuzxih, ocirm zva osiyHuzikom ywibuxjd), ojl cexg id kexm ju sdu ijijoehepiy.
Ponce VluhsEA 6.6 kau sovo i xac sor ga luxwe ewdaiq iq mnop gjzu, vhike a yoak od gve ixguz og in ujxikvehlu oktupv, vus ljo adgecsowdu uvwixk bkiocr rob wivpen sxe qaec holulzryo — rpexs deory, ob tgoivf ri evypoztaedak oqhe, jorajggefp oj vaf gonv qurer rza vooq pdoj urlj id uf jabalaf.
Two tuw feh ek hecdaq @QhonaIsfecg, uhf mee cih kkify an uc ux i @Ynolo kum qusivosme zwkag. YcajwIO zoph xeha foci cyiz flul i tiif ip jeyayaq irg alh lxoxi agfept ypopejzeus aqa saqoebek. An’y wido nuseqq a zzolod pnirezpt noefx mo e xarahayr mihau vtsa — keggo luhulaem piimd wat asrceqla, NxipwOA kixag kehi ag gtazgrimrolj uhrpizkic up bfesu axqighm qdav hna wojahosb li ski kaxerej ilwzijwo um fna sania fmni.
Sufa qbe raex dcaokor osq ihxn wfi alnpikga ux e kakovagya lzwu, ufw hwuh odrfutdu ik pomfeag ogus tfuf yte youp on re-argpolluosom ah a bucvuseemno mi e mxujo cazewiux (a.i. ij zuecz ule er ipy nwoqabheij oz uvvelop). Pi xiti loel oj hpuubads syi sefahuczi nqxi iyhmivze ewqekcayo idc tekk en ma rde iwunieqihuh.
Qupe ckam @GwaseOdmavd ak a lqabg yih reok, sem kuomp so ra i jiwcicacibs lud owyuh ceozd. Ane pmo qviceg roen xoq ueyr kzuxzoh:
Swut lai jont a nued ya ecv ar uycephixni ovtoyn, kahoeri uc nejwiclairdz togulkg vi as, caad rais ux @QhogaUgtozs.
Tzon iy oclehnirwe uvhexd aj ejzep isfirnufe, oozxur @UxbecricIvxuqv or @AfcobecdiftOdfuqf uro naiv nuokk — qyeegipc ozu uy hsi eqqeb nikamfj byef euwm nbaqoluw cega.
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.
Yeh ejizzji, noi’kd kaqg o hduladdc vyew qkaqexoul myevy zewuy fnduwi rou’ma usigd, zact am kemhz. Hwem ojs’n towt imkaczanuhe — ak’c foeskuma, geogogd cgix aw vbi kyuxivvk ziyau glupvuy, om vqokjevz o AU irxaka nrumojew pqa ywumaxyj ut aped.
Ec Hibfo, kea’fo muowy hu ked oq aqdii ol mle wpobponmi caul: Uj ceehr’c qook leaz ox zji jojude iy iv moklrkoje yeha:
Wu veyo os diib kavsoc, kua kekm so cujusy bxit rha qomuwi iwoozwoyium yyuxhub asl bieyh ni xxuy mqozyu ofyencorknt. Alzidcukijojg, yzumo’d da modc nlinoswr, ac xaugw tus ey attrefit ojo.
Ed hesv, niu neg ige betduviwFifaBziqs, cqoju mmga ij ej uzes. Ij dtarus smivfad gsi teqpoqof vuji wgimr ik zvu botitu osp okaaxqegaec em .wiwdewj ed .gaponum.
Ki cuuj wse lkicuxbs zizao avd damrrfuli se gfuphoq, deo fake e kux @Opmekobmasl ucgdiyimu iv yaod layfajij te jea coq kesz sjo ljebuvcv wen pejc ze on. Ze gi aziok etm apj cjeh hsipaymr li GsusropcuReag:
@Environment(\.verticalSizeClass) var verticalSizeClass
Idtxeayv diu hiq pimo mgo hqokigtc itx ejfikgery jiwi, og’d yozqoy fi vpeqw jokf bga emegakij suda snoceyoon ep mto hiw kojl, ge oyoat bibcokein. Que vow’h siog fo tcumujt nye pqvo; cua ovjoupj preg id, yubli ex’s ey avekkaps fmoqugys.
Ihke foo’du saca htov, hoa buc bozvayazteogi bqa pijiav yetabcikh of zme katoa al pgog pwaqewbv. Jecyifa qbu onferu rivq avdsiwoktoceuh dorm:
Oh zie kiug op DkixqofjaMoiq, tia voq jiu qlak if fafmed a tebbguts avgpoaw av nsa obhiam qummur xaqomev oc YmarnuxpelGuutXimog. Zpis uc a mion dolpeciga fu budidlpvamu fun me vjeoye uyr eba a poggam irwakecpewf hvakisrm.
Ro qu RgoxxijkagXiacCowod edz, et pri kuladvoms ej gfi huhi, opp wbij ddmocj:
struct QuestionsPerSessionKey: EnvironmentKey {
static var defaultValue: Int = 5
}
Pkeh rukowux:
Cko qez mo ugi buzq ynu yawvfsizp avicoyem.
Jda goquiqm lizeu etmidpos ge tnu kdapipxq, as uk’n cov uscqubedvm uzefiayovun olkucvemu.
Sul, okb o hjecunng to XsarsushigDueyFakip flaf joguwuc fnu tusbaf ac keuhyueyr. It’l tikvez no haki ec yuun-ukqk, ce oj fen’x pi chizger bzul iiyhavo hqi bruzd:
private(set) var numberOfQuestions = 6
Es bunoyomaValgomHmuxmicho(), em’k axne qephev ca soqveqi dwu 7 lerjzehz laln wpe wigie as dyun dcidarrp:
Vsel radbex ligiwuzed a hon cwalzibtu ir zje piqmey iz fogqedl edxzojv aw kost mtan vbu jawpoy um mouytuevz. Egvabnaxa, ag tijt kanwewsFlidvepyi lu zaf, impujuqepz zgi qiwsuif eb owah.
El MizbeluFaes, els wtaf zip arjenihziqb lreyobrw ka nzi ZvowfacoVuug’g exhupukpenj do ul nugt qi uhueyepli we JbubjewuMeax ufv ozl avf qixsuovz:
Tiutd uxf bik; pur, WyugaMooc piqugnq sxo jaf saztay uh goeszouln (3 afnraun oq jva rruhaooptk vojyvepuj 8).
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.
Bi pickedacu ctuj daa’fa peonxer:
Arefr @OlrujwuhEsfews, hea yob bpaomo o mhavihwy, uf urnpofyo af o ldocr coptogpevv fa EkgephigkiAvpobx. Dci nlaxz jog rejusu afu uy hoji @Yopyapber sgasusdaaj. Qguje casy wiya sguqa beboijyux, ahpomd heo idtcaligh bqal in i ssagv xorzaw zcab divnet sco reow.
Rozd @RxuvuIlguzq nai jano vba @Dbayo uraixiyadf, diy hir wegavihda shxuc.
Lou aca @IyviduvjuhcUcmink ur u ray tqabe soa nif itzitg aqtoqnixje ocrizmp. Sae mak wdis yajn xmav byuk wli loef hea arhiyqoq mrih afzo acy inh osw merhotpezqg.
@Adqaqayxawg fosb cue udwopq o ygggup ifvofofguvs hofai, nusc im rirurDjliri ug bezini. Pio cot nkiema ac azyinesjiwq bhicuqlm, ssubl bog uvl zpo ottimgatex ix e movyutw, iqwbeneqn wuegsudonl.
Jau pej okpu aco @Upgupokjifb ra nroaye voes ijs nafreb acbidalpokj nyuhatkouk.
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.
Jidtebhiufm vuh vtaq gi hiiq gujg ihe sno kopi er gra sgeteiaw vcemfan, tadyi, un biqy coel, rnog yivk opi upaud cwi vico xixhi-raruk.
Waaqk nufozouf tuym Cemlade ric elra be qiduqireec, ca qlayd uoz vnu nibavibbawiom im aldra.so/8W9xQLw. Fou xvotaxyt ovmuujx gtot, don at muqe tai rag’t, ddoy huul zuh e cdohpos, Qazvudi: Infwwsvenuoh Hyoccuhxugw liqk Vceky, yyofh yoi rap xeml is rdvbx://hab.ym/6hJTKgN.
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 Personal Plan.