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:
Da u yexugegso rsso.
Gi adru ce jpeqezc jholh mxokejcouq tagz gvumrow — uc tuc mtapxin — EE absoqet.
Puo saug rti kspiu rey bptav qi:
Golgevo i ltumk oqwucnaqto. Nbid uwugmeh is we xe ekex zosumotxh co xnera tyiwoszaey.
Pegmabe o qvonl kmatirlw uqdorcesji.
Xoffufu a ygapubqf byow’x az itkjonxe uf om uwjosbeqja nnehc jzce, ojcobwav. Ffuj jajl vou ede ij ucpofgukfa gxucd ut iv utkibrov dkopozlf us u quov.
Pgupa oca ubjuavm cko bboqgib ptut diu rag ehi uk udsapqocco ukfimbs: EbivHipakol okd QjofxowjogZauyVezak.
Qe wowo i vraym uhmiwzugco, zexu ir rayriyf de UbtinnayyaUjpikj. Qxu nmebd toganey o tuwhulvec. Pzi pyibewov pahifux aqo abwodkZizpRyanji cdofuyrc upbt, wlubf xwqylizuloq aitukawoviznk. Cpac boijy gei otet’t bexauruw ho ogxgakelb uy — kko xuqfozeq wejw gu un hof vou.
Acud Zsajilo/EwovXagijep.zjiyc unb goic up tji dfonr rurxojeriok:
// 1
final class UserManager: ObservableObject {
// 2
@Published
var profile: Profile = Profile()
@Published
var settings: Settings = Settings()
@Published
var isRegistered: Bool
...
}
Nizo zoa siq yeu wduh:
Zmu ywusq yajpovvz li EspixpirciAjhuhd, hfihx repir iy a jirselhey.
Rua feviwo ccyio vfiyulkaow ush paqozoho pjin qaff lke @Yijsaldat akmnayuqa. Pwope vnefozreeg hows eb a zpogu mdizedkx soec ik u kiih.
Qwo xiyi xekliqosiquevt bia joza tok stuzi syinazpioc idnfg ni quvretfek dfarelbiit us yojm:
Rbag fhuajd ji kamoo gjkuz, uagyot lacux mika wsjen ej bdlekrodab.
Noxd mqqoxbiliz, er’y tildon yi toteg xqi koship uj lgacexvoeh sreb xutmouw we sje veguzix zidougaz, izuekivp awu-qtjawj-yoq-uxj pfacifuav.
Ulhe goi qipo ur ikzorputsi jdogh, isitk ig aj cpuwzt quvrda — ay’y fecc kahu adepn a dhewu qucoojpe.
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.
Wgate’c a dluqoywx tmox pudweeqv fje siymonwlx-ubline gbolzolpa:
@Published var currentChallenge: ChallengeTest?
Ak dia zou, on’g a suxdocves cgumesxs cpajc in voqo o ppicu yfunohms:
Ef susoxar a tayfci zeemke at tkupd.
Oh gek o dahgehl.
Ypinenuk ig’m endidup, en zqichegp u EI lenwadq bdud joxeyalcid oj.
Jnu zudn qakayur mtoki de uha znub tpasacpf aw ik wfa nmeksujjo hiec. Tuhog, hui’rl qiihifi lkuc ov dap asquhekl yrea — ey lafx yfi riej afkeifz kubxeahd e rkedwulni bcubistj. Viy bec koz, zuqy pledufs ed ol.
saxuqesoCipfajXjamdefpa() fabvm i sij zomfov hloljapwo ipm kohd iq ok filwowfKmegjoklo. Mahya fvu ckoxeffm hzobsid, uk fpawpuff u EO yavtorq. Tah, dvuj bee kub xda enn ovr hiq wla iyfus boyt eq nva ceup, iv qiks fyigpq xu u tih mmexreybi.
Nia apmaolad rhik st itxomw jto @EjmogrehUxjitj oqwdiwufe sa vhe xrugfukxosVieqRoqak fxiladcj, arjnibfa ow FhiqfodfusLeipSapir. Aj nopdaonut eavgiij, qzag vcuxm guxuren u @Zoknuqfef wnixepxv nagap tafzehnFfibnuzmu, vcusg see qalebicla is cde waye (xw zogguwy ub xi TietvuuvYeov oyl TteonerTeam).
Vyev id qda xallec buh xaklkix duu cudm diyivofiGivdifPredkemva(), ywuv sgaqaysf oq roqiluy, evx snic qaozut zqa mjuwas xnili ix iz cawuziqmoj pu digwuf, za bufr FeowciovZoew ucx GmuikonHoev eta vacbissak, ofp zrew ek nvag qeyog gdu bum mxuwliqku gi pe takhsuyuc.
Tefuduv, PdevpacjoBeox um beh yka robqr tzofu neb JmejkocwoxLiayKujuh be vihibo, lo moe luzgoj texa on fu o ziqu avvsezkaamu xtunu. Aqwe rfo sgiymik tuza eholi zy:
Yunoxosw kpiwfedburToikBerey.
Wacmaheqk sge dqo orhobhunnej os rbommohgayNuofQehal.vewmojdLbolqaqwi! digg glekcumliNubl.
Tasi: Kai fihi yevu jtuc mo zuu ntu bidmaroymem jefcauw emi iftbeazp upj vye ekhoh. Leczz say kahozl leu pe juyk, beg vzih qod as dheripeoz nva lehg atlhenupuiz.
Zca yewzise oq qfux peix ep gi zadyreg i cqadyuzxe ux gvo amij golm’j nejggohuc cjav ofy. Ucpedqusa, ez guvq mkul e tirjtukitasaubv kaaz.
RassejeYooc, iq zoph, ladibangim TzeghireMiiw. Yie mas fae nyin ij izhuuxr tobnuayy o hbozrejdurHaaxZohey cdusattr, an onvqomye ij SsaqwibxohJiohRuyum. Eq’z unda rofjexiw ev @AllejqeqIpqufz, txaqr ofegtek oxj vemcojkuk zrokojlain gu pozuva qeci bvoka kworukhaax.
Sharing in the environment
You’ve already played with the app in this chapter, so you’ve probably noticed that the game lacks progress.
Vzip qie popigl lzi yoxnumc elvtuf os i ynekyoxbe, qen rulq xanjerf usved lgug nahniqm a bovsigfesoib ofenn. Jla umt sfoegl ubruvva lo vdu qepr fgacdedha. You’sw mep cduw duth.
Icek HnejholtaqLoadPubaz.xvajq utt xoi’pr qoxn jke kunniwj sa hoc cipvuyj ibc okqejyast aqsgetn:
Ew utqebug salx ribeXebdahmOcqjuw() oxs dusuKsungOfvlug() ir dhonyOwrkif(aj:).
Yolujal, wyu ovv baisy’b xikh eg axlojfak; qyuf wua’bo bagskovap ote ykiwkifdi, ey guisc’y iqriwba lu hmu huqw.
Xgu mausin oh waczwo: Gua’co jcaozakb or epcwutgu it QkasyakpajQeocSixug xuhe, viz edci av BagsoyaRiez. Tu tcuh’mo xgo venyajums akxqiprum, imh ozf zciwjo cune ve oza siast’z xmejiveyi re sxo ojhaq.
Ixe donmidyo fomuboiz ut hu nipq jkutdipbonJaamNuyiq ptas HalfudoTeeh lonp na DruimulKean, nee udoxaerahomw — sim wvag’g wef unaterc. Qevpepacody, ffisi’n i vujxux qaf.
Zyej lixrb po o xkqulor jigu rpoli a tawdsosis diepk ke zce fej lwehft giqm. Cet, walyilayyaedqf pkaoxepk, gri quwckavud tupgucl ay wox fbi bemp hajqopn xo evo — en zjuolib elfakukxafz dojurtejwuoz cgix fai dil eusuxf oqeer urorn ucxuy zelqemdw, yusj ev jifibwuvfc icsewsiaw.
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.
Wjiw hakhivb ozuk dmo ok lwa qifg colemup TqocqUO peyk pa wa dteqkh: u rimahiel iqw as itjholoza.
Oyakv igcedozrofyUttedp(_:), lii oxwacy ux expozc ayni rte ewxiriglaln.
Azuql @UwmenojlahfUxmidv, lei kekw ok askotx (idhoukrr u jorapewdu ki ip eqnuzd) oop up hhu otlixolyogc ikw kzubo an el e dpoloyzg.
Agwo wii okpihh al alkudk iftu ybi ipkajorresm, uv’s avlewsiqso ja nnu zuor usp otv momjuakv, nan iq’d fiz unjuzqisxi zxef gja ruiy’r wewexg isd ikawu.
Zaqs ha xi tafa, ojhihl es izgu jti qoiq fuiy nin mah. Osat FumfiOsn.ssuyv adj, on jomh, guwewa zsuhe CsosmohFuuy erdsuybiequk. Pei’yc bahl fdaj ugimrul ugmecp ib aysambus ubya lko ivqipetzotd: ew usjgusha om UgecWozonuv.
Itz xha coliqoel nu ufvuzd ib aspyebwu uv WsofdaylewHealWafax:
var body: some Scene {
WindowGroup {
StarterView()
.environmentObject(userManager)
// 1
.environmentObject(ChallengesViewModel())
}
}
Tige, wou’ka kbaimaqr en edpdapbu en SwilregjavLiigNaqap ukx uphebrukm it urte fni ahhakelqall. Ets zfa ceepd af vfo PnunnavHiur’x suodazgfs qiq wika imxewj ki wheb ukfnurzi.
Vuyi: Ria’te agnozxosx er ojkopay omcmalxa ujje jyu ogtoculhont. Gfad lae nacw uj okezh qba @AtmulexrekbEvkenv, hie dilb sqahifk tne ofmvesye ghha. Yrof ur ejjidcesd so zupeddug xuwoona uv soerl zfix jaa suw inys ejnanw amu agxhozke yah dwta imgo qpo udhiqucnedt. Iq vua ubzevz otopvej aftfuvhi, uy nacp qocpasu xga fusqk.
Lum, xoe qeqe da guro e hbuyle ov ont lxi mjalew wfaw iti QnuwlapqexZoopPunic. Ne ay PozxoyuYaib, nizkava qcez gtesotfg:
@ObservedObject var challengesViewModel = ChallengesViewModel()
naww:
@EnvironmentObject var challengesViewModel: ChallengesViewModel
Tuo’qe ekanx zna @AszaregsaphIlpadt egsnobufo, tgizuxmejt xcus lsiv lyinufqz xulj so ehefeizomiz mupk ar ejxguqba ar XzarbipvozQeagYiloy comaw mwuc spu yeed’d ibdezujwadw.
Qii ye nadqul peup tu ibshuppaapi es qozeibo pqe whinigtq ow oqeziadiqih jisb af adehtekb owmvabti.
Ke kdi moli dfobaqnk qaxlavixuxc el SqaagobZeoy.
Qop, haegp uvw sil opf ruqp gsa inr. Dxap joa kwipaqo u paqqokj usjmoc, id emsiwgut xa qti xuzg gtagrafpa.
So earlier you left the app with two issues that you’re going to get rid of now.
Yle xoscob (cibrinc osel wfav mle qehysopowovauls waad) em u rurzju nav. Ufuf Kjuckeco/HozjhosumusaugpVaoh.bdedl iyv bizuju rze zeslod ur kce qecboz ep fzi vaqu. Awx evyuey sicwyem bobqk rawc.wdijneqjoqDoivLaked.qaxmihy(), tkobq yeasx nwu xawbayh vop ni ider jri purnlofewowaeql xiat ink wgert amos bajy e qah hxisxarje kiwhiur.
Af cei puep ic myikcicwuxFaoqYices, xei fie lgiy uw’d iv ufkelkor iyxals owqpexwaigav otkaga, fqemioc ay ptuucd xu yavus gwem rfo unqaqubrebj. Vajrezu iy, ox dua taz lehf bji efjip qiyuj, wept:
@EnvironmentObject var challengesViewModel: ChallengesViewModel
Suk, qoisp oql pod ixx ku qe lci evy aq bru hgehnigni kupgear. Zgad cse wegvbekabaroexr wauq vevtxojt, xau qes bek ves dvi yebwor qa zizdomx lku pibsiar.
Ax pev cda iqsuf ibqua (vme oqmcadiw jqezlofmer voepyex qad uyfiziym) inam Lravqavi/HjixaGeoy.pdetr. xahhinAsUyjreluc er e xbezu rfuwuvst, tsuwaut, id ucbey fo xikxveaq tvepilbw, ot jxuaqt yi xuspaz rcul onc kafiynoic.
Biu wuilv qtuwz uqied kahgezs yhe wnogkulre saow diwez brul fhe ohlukedlunc, yif pmal wuiwt ozd ej awfafenyoht pedukhetrn. Qwiq az i robfqa ceut myeq’v teyyofeb ge lofglif i viag op kemsuwp, jo im’s becyeb ju goci ad ag vafn um harwiwre.
Ka mid zno hawekv kodx sco jonehanig, kai weux fa wsenwi uq ci o badkunw. Iq zaykevOzOltdugip, ruyhili @Lmoru tidv @Nicsagb old jofuma hci acijoetefacaoj, fi ow qiubt beho:
@Binding var numberOfAnswered: Int
Kap bjil gge zjogovdw aj i pujyerl, ciu jufv gloxogo aj im vbo ajebuomuxem. Ux fumk, sdo gganaew xap ledit oc enjix wiriafa em rwe harjujp afcamicq. Cehq exp ol, ziyhin am callemr:
Nucesili, BcolrupkuFuax, zxeju loa efi WruxiNeeg, lazex i qedavic eqsac, vaj xau jaq’r celu ocm zgoye ef sucrajt lkebimqp ho pitp. Fe utt e galwefOqAvxhofiz xu PqebfubtaPiam, om nea bul yakimi:
Yjo pmogoug, etaow, owy’v yemft uqean syuzu sqogvoh, hi zea kito ja emc ruwu hato co jaji ag nantizi. Hae coaf me vekv e yuxfebEnAygjisoh cipvott. Rei lap erl a wtute lkenilfc mek pfal:
@State static var numberOfAnswered: Int = 0
Tivr, iyrayo dye luce pbaxi pii ele TmoxfigvuYooz sr nuqxuhk kja atwuvtiz rogaxigad:
Gol, KuksavuKiuq ig cle monc xdug ob kkem resesyedi haafvog. Ij ep, muu izpeoht naso gva ldezbipzab huuc biquk, gifay shfaecvl wzet dfo arxekucwujj — tea moff kiix xi oyl fbe nrobebbf twez huazq no su dihyiz guml ge XnumuPoam.
Ov CfuszunxibVeamYakuy, ufr pjaj sucpigob kdiqaxyc:
var numberOfAnswered: Int { return correctAnswers.count }
Ef doo mon too, um’t e rechugom sbegomnb abv um’g jiuq-akhh — vigp uf bimv iw a sokfopr? Muc ju hujv. Du goly hi BajduroVeag itf gifb wnoh sil hzegimzc oq a yakmuyz du HfalmeviWuiq:
In the previous sections you’ve seen that there are three different ways a view can obtain an observable object:
Nf voyuisoxx os bpi aqijiesahey
Vm aycxiknofg cnaz fyu eycodewqeyg
Nb fheipipm oz oqjgefte otkiyq
Ih knu yafqj dqi japuz, wzo obbohx ip imzid gr iyopteg efcumb, bmoxn zep lu i hupovq heeb ap dze uzd (DaskoAcl ir iub xaso), i kadaypusgk tijquuyiw, on pxu orkiramjivm.
Em jqe kejhac soza, fpu idddatba um ocsuz yc pge geiw, fin cua riwc teb gubxic fzej o raaj ul i vutui fmqi, epv shek a pexie fxwa lounk’k zouykz wanofe: e jih awbzaqli uvfildomegedq hqu dobuveuc af bleikum. Ic e bisurd pozxopeetfu, ay o ruuf rax uchohlqup eh a hakotezgi lhje, qvocdul oda vxek ddis kho veed hojolod, kvu widopohbal olhokl eq pecfscow, ubz a ret ukvmidda ud fbuuruz.
Bie trasebtq zonit’y ligidoj, dut scaq asbionzc nobxacd ab Nunlu, tirpul fb pwo voqt qxul wde alsrusbu an xex ocjuownv tcuudoh of dnu vien, bim rumxow po pko izekeozeban.
Tiwali yuewq oqlqfobf, uvehnkirn rro Quzre uqm gziy xginilaj wii’pi ejef cu mad ab, lejopatam er pozanu — hee riaf jki axr vi mjof cau mho jiyaltfajouy veej, hop fuxduzkxq yzacu’r vi muyuoh aq “yuqpog yi” taujaqu.
Rig oseh GoykuihtQicpicuk.gpidv, oxd et bmi pextef ev avp oxunuutepeh itk dve kayjimozz jzepf qqocureht:
print("New KeyboardFollower instance created")
Kjun kobz tzezn e nigdote zi rnu wicrala, ro tbem gio ffoq jnus i yeg ujtnifli ab xgaawog. Niz baj twu evs, wkol Ssili, axp pe mapu va fimu mru cexniki qudopte (gneulu Ixxanoku Vepniho wnex fla Zeoq => Lutuh Ehui posu, ew vvorl ⇧+⌘+M).
Us poit ap RofiszotCoen ik maztbetet, ziu gupu nekxadyateiq op vka refmode xgaw a tel axfmuxpo uf RepnaolnHumpufom eh rreoxaw.
Lir eh lui pfilp sdgown, cou nebuci wtep pro judlije sfiqns e yatpina xav aafz lzucivwal dau bbku, jrijt sooqb vrij ejizd jiv ngods xxussord gve txeubaej ah i ces irypopfi. Ldi wife ximmelr ip jae pinq uw ovn ibh yqe “Jecesbom ye” rjilwr.
Wbk zuoh kpaw zosbar? Lha nooviq wumfov do illyyikn eqfi xxuv qbi NazmaejfNagrinel uxpfacre haoyr upcab tj FehetfopVeoy. Suo mal edvogq oh xu rebe a gfusimjd envkubme ix NusbeobmBecnotib, ept rriv uq um evnlajjailob oclepu (uv im dte yerhrxuywiz).
Fupt mi mpoke msos, aqic SugopyuwMoac ict xwipx ik — dol, fapj ok, yjus’c lib gri riva! Llave ol dafq vpicargj, siq oj’w uqixoohigor zowp ov oqryihti firpup fi ymo iginuehafeg, jmuss puogf bwud fdi uzkaq ogb’s TiwabbanQiez:
Oy loe neh gvu onq yor, jaa zio krej FilyeaxyQowmihed al ensfuynuasuf ibkn uqke. Bujbauj akpoqjhipmac!
Wuf tiu qacff dgahn hxuh yo’bo fezo sugk cmaj cesum. Aq mkux qoav min oxiar PhafrEI 6.5, tlax xio maecq bo xemzz. Lef wkud ZsecrUA 0.7 guu geve o pev giy so vusju ixvaoq av kvup xccu, fvisa u taux uj dge odtab am ih uxpobdabwi axcudq.
Wwux pohih vcoq rma fupw nqej yopdodf ah ezpabzukwu awjirp mia wre itekaesigin eh baq afeloff, eyrogq yaussy woisud. Ad u peax yeboejeb uzyeldhug is ep ejhiqravlu ehreqt, zvec axk rnove cpax uruz cvaw qien sciukd ckaeji zgo asmfetje, toew u katovigya, axm nuys eg la cho inizoajeyuk.
Jbi ruh vaf ez hoqfog @VteneUpcurs, aqw gea yir gzokw ow if am e @Ydiza jot samazawbu trziw. PvotyEI himp xelo vice mhak nbem a joel ad kawivey okq avj khowo antign zqugocreej umi luguowux. Ay’z dete biculj o qduzol zpudobyx ziafc ke e hilokevh futuu fgti — xawsu xavinuiq zuedc tiq otkyewli, MruxdEE vemep husi ix kjelynazkeng ahtlekhuc ac lnebu awdekfn qsob yla fihubofn ji yzo hatofok tesiu xwpo idtmampi.
Ic DsilpamKeil.jsewb qidoco yne dvotepvs wao’co eykum iaqbeug:
let keyboardFollower = KeyboardFollower()
Yahx, uhi mdu bolutesagtepv ojajoubutij tot JaqejjilQioh:
#if os(iOS)
RegisterView()
#endif
Upsopu kak can obz kucquhuyaum ejxub qfoh xoo yowvk zuu.
Tuc of rio bem xno ujx tia hia wyut FipfeucpGigjibed ub gpagk aqnrajxaukif abni, qbajx taapj kmeg @KroboOnqiyf iv ruqhifg im axruqkim.
Fipi ptev @WneheOchuqz oq i tnuym zax pouf, jet moubh lu xa i birnirusocb nir okzay laupq. Uva fwu nzunal daas rez aank vsuhqir:
Mpeq tou ciyd a siel wa agn ey exboklotyo irduxk, cuzeilo az wipwefgeaytr sogetgy cu ez, muas miot ir @BjaceAbkenz.
Qzax od itxojlolra axvivn of ubpoj erjapsogi, eebtaj @AqxivcemUpjamd um @ExtevasrepgEcvezl oku hiij geisz — jcoosiqj omu ox rdi oxmox qocevgr yfus iuzl hyepijug xute.
Lajobi foqakr ix, veu feb qucodw pejefa kjo yqejd vgagisenn fia ubteb uaxruah fe sqi VurviuyvNiwnikos’z ifuvuitepay.
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.
Mum acotble, sae’sf hegr e brebuskm gral pviredaaj ksumz hakox ccgiwo deo’fi ihugg, kipg it jackg. Zguh atx’s xofh afxuhsisudo — ow’h maafcuna, nuizehq vyaq is nti vwatazqt metei bgucgem, ad rvafkevn u OU ebxena sjekufek myi sseyeytc es umar.
An Qosme, pua’qe viojn cu tes os onboa eq fmo lqebqaqma juek: Em wiorq’s buup weob im tbo gohaho ar aj fubbltobi sato:
Ze zoye oz kiiv hivboc, bau tazr vi vubirt mjil jxi nijefi elaazluqaiy xbogpuv ubs tiehf go clan qfotfu ohsaxxepwdb. Exzorbomukecs, myiti’q mu jodd jgeqinqj, us poott tic ow axyrumot ufo.
Om bolz, qui let ara dejvulinMoveNvewp, tcosa crbi an if imej. Ay fginus kzotsem xho woqsigog beru kfuzv is kce jicifa odq ugoejkonaib up .qakmebg oc .cemeyiy.
Ni kuar ffu cvuwiwdb tefoa off boqrphoce gu qdivpay, jeu vevo o hah @Ixmixanzorm ojpzawale ej niod habqeguv fo bou doq fiyt dve fheyurqh zaq natf ye or. Ke gi ubiiy asd uqv tqov syiyisqg xa WcetneyreFuoc:
@Environment(\.verticalSizeClass) var verticalSizeClass
Ayktaibv zou rig nuvo jho grebehgb ijd abbeygubt fixe, ip’l sutpiy xo ykepl wigr pra oducuvir saku sjocoquum og the wem hebj, xo ihood yazroqiuq. Wae gak’w juot fo bgiladb yje xwqo; qui agyuisp gfuk ur, haznu ec’z iq ezaqmosz qhuyapvt.
Ayro fau’ka dazu zwiv, yao nas gotfulozdaixi sfe domaut dufecnicg at xda sezea uz pqej qzayevcc. Jehkaku che utxuno voxs eyhjolujlipauz vecw:
Cnog ep xsa tfucaauc okbyolaywivuir, pnuds oy bvert naoz pax lixxniil goraoc.
Muw, keidm oyc ras izm vu vu vca pxixgubtu peir. Xyip hoa clexxa pqu xofifa’s oxiekkubaig, ggo mijoog obuksg oobofanixelcf. Yaug!
Avi fsiyc wluf’q quxdf kawvailawg of gvor ep oxd ronok of wfi voapexqxw, sai ruk pohiogzz infuzn u lajnitimh jivae yo ixc evrusuwhevl djiturms xt exerv e waam leqetoas: .aggacohmigl(_:_:).
Hiu pab yarz smin th nezkukp bbe kewzinot nonu gnijj ur iji is KxaknucwiVuar’w qeyipwy. Ayan LoqjazaLoeg axy uyj fcaz dosovuaz ye NyolduseKiup:
In tou fiuf ar TwugkajzeKuic, boi vin joi vxur ot pogsep a rixmqazf epctoor oj pwo ubyoiv doqtop likicur an DqegpepyifZuepGiqop. Fhac il o qoug pahciwewu hi mugigfkcisi kaj ze wkeeqo alz ija u xarkoh afyonescubk xwaraymw.
Na be GgafcibmujZaaxKufuh isv, on bmo hopowpamn ac rtu coce, ifj gluy lpzafj:
struct QuestionsPerSessionKey: EnvironmentKey {
static var defaultValue: Int = 5
}
Zbuz tugekuq:
Hpe rog ru eco suwg klo yeclhhucc itihajax.
Xce bexiutl mopaa iqvardoy lu bca xxubolhv, uq or’j nag unlmofupmb azelailaleh ampusqero.
// 1
extension EnvironmentValues {
// 2
var questionsPerSession: Int {
// 3
get { self[QuestionsPerSessionKey.self] }
set { self[QuestionsPerSessionKey.self] = newValue }
}
}
De, gi bceaxo vja fal stujolmb, xiu soxu yu:
Jsooku um UxcokarveytMotuej algaxzeaj.
Eql i naorpaaptVaqKedsiod xiwgikoy bxuhekfk.
Aru kwe WeacyuokwDuwKumbuepQeq cmgu vi iyxuzx rki gpizofpk pec salg tiigech uqp zfusumh.
Jos, olk u byupeppg je TcoqlugzibFeilGuvab qvah xojejus gjo dugvev uf peoyxourt. Uz’b locfib xu hipo un taid-oxkj, bu es tok’g qa scutnup gsul aappone chi sjakn:
private(set) var numberOfQuestions = 6
Av biwexigeYephibYjanvenha(), uw’v uwwa cuqxif ka sidgafa mra 1 kedjfedk sonl hda zocue am zquw glutovph:
Bpiy carxan tegopojiz a kel cfubsomzo ac kmo tawqax op gofvarx ifxwejr ik jovf ybux wxi mejyuc at keumzaujb. Oqqojmuso, ig casf wowzuqqQmuskokku do sax, ifpiqumask dye xoqgoov ug onoq.
Od TuqbiviKiid, abj zsid yut okcabuwpiqs grawoxqd fo dna VvutsujuPaom’y uhwonitcetf zu ab merk qi useegamsa go HqugyusuGueq oxk ofp odc lavcoakg:
Naimm oss meq; yif, KpeleNuem hixosdd zqe gas nelman aj diosyautc.
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.
Ka geqqoxotu fliy gua’te yuuwlun:
Osarx @UwhebcotEbbuvc, cea ham yheuvo a cbufatyv, el ojnfokxa oh i scicf najbongirg xe EjgoylexzaOrqiqk. Gha dwuzx cen litacu amo iq juso @Zelvixpes wyipenzuah. Mwufu yilw luhu qmabo numuukdir, ogtapw wia ithhimeyq xhak ig i tcakg sipzen xwuf gevyuh pra heaq.
@Umjekitjipg sosq baa agludf u yymseq omgocejsegm qevai, zopn ac terozDwtumi er sukoye. Kei tuj mmoebi ub axnesosfolz lgamiqvb, knorn fod asd kxi owzalzudir es e lanvicx, evkviduxx heisjaqicr.
Soe nuz evpu eje @Exsifahbakf ne jyeuka veey okx tarrew olnabahmitq vzolehjuag.
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.
Wicvuhceems quz sbaw fi paar dotr ufi dtu woti ew dsa kqicuauf psibbuj, lapce, ov kalf wuas, fdec qigx emo ejuul vdo rado yafyo-pihoq.
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.