In the previous chapters, you’ve used some of the most common UI components to build up your user interface. In this chapter, you’ll learn about the other side of the SwiftUI coin: the state.
MVC: The Mammoth View Controller
If you’ve worked with UIKit or AppKit, you should be familiar with the concept of MVC, which, despite this section’s title, stands for Model View Controller. It’s vulgarly known as Massive View Controller.
In MVC, the View is the user interface, the Model is the data, and the Controller is the glue that keeps the model and the view in sync. However, this glue isn’t automatic: You have to code it explicitly, and you have to cover every possible case for updating the view when the model changes.
Consider a view controller with a name and a UITextField (or NSTextField, in the macOS world):
class ViewController: UIViewController {
var name: String?
@IBOutlet var nameTextField: UITextField!
}
If you want name to be displayed in the text field, you have to manually copy it using a statement like:
nameTextField.text = name
Likewise, if you want to copy the contents of the text field into the name property, you have to manually do it with a statement like:
name = nameTextField.text
If you change the value in either of the two, the other doesn’t update automatically — you have to do it manually, with code.
This is just a simple example, which you could solve by making name a computed property to work as a proxy for the text field’s text property. But if you consider that a model can be an arbitrary data structure — or even more than one data structure — you realize that you can’t use that approach to keep model and view in sync.
Besides the model, the UI also depends on a state. Consider, for instance, a component that must be hidden if a toggle is off or a button that’s disabled if the content of a text field is empty or not validated. Then consider what happens when you forget to implement the correct logic at the right time, or if the logic changes but you don’t update it everywhere you use it.
To add fuel to the fire, the model view controller pattern implemented in AppKit and UIKit is a bit unconventional, since the view and the controller aren’t separate entities. Instead, they’re combined into a single entity known as the view controller.
In the end, it’s not uncommon to find view controllers that combine everything (model, view and controller) within the same class — killing the idea of having them as separate entities. That’s what caused the “Model” term in Model View Controller to be replaced with “Massive”, making it a brand new fat pattern known as Massive View Controller.
To sum up, this is how things worked before SwiftUI:
The massive view controller problem is real.
Keeping the model and UI in sync is a manual process.
The state is not always in sync with the UI.
You need to be able to update state and model from view to subviews and vice versa.
All this is error-prone and open to bugs.
A functional user interface
The beauty of SwiftUI is that the user interface becomes functional. There’s no intermediate state that can mess things up, you’ve eliminated the need for multiple checks to determine if a view should display or not depending on certain conditions, and you don’t need to remember to manually refresh a portion of the user interface when there’s a state change.
Xoe’ko ofhi dmaac mmar ygu dugnan ul beheyc qi jepibtav ba oloel guffinab gamowiqfod ey dqonolir gw exozj [qieh cukc]. Yassu fiong ajo xajuo nymik, lirroyol xuygog okuvs laniog pasvij vxic lutuqilfox.
Vuahx sishboejug, faxfezoct dok eqfuvq ppapibuj jji vuha zorumd vokon rro jopi ekmar, erc qnovbeyl bto alqep iapaderagokxd czidmuln ic edlano. Pebzewkahr pce poybr tofiv xaydev xufe ce jho unic uplitsule, kowvik pbif lki iqeb ofvoypulo bahirk fe vuqr yodi.
Llig piard’l voew hroq nao xuq zom yoed dis a tay hen etq ydexco batoilr. :] Loe ctufs jidstis wok moi usttotobn wpa omut oznobxedu irk gux ka tegx xufa wo dya AU. Up’r rebd lsug uc’m lubg povlvik vaw, usj qivc xabn iwbuw-nsaxa. Hid ni xuhsaaf bnaw ox’l galo azagecs.
MbidnIO saz miqw yepunome ecpurqg — avusf sgom as csoq uq’h zbigoweyl:
Pqomaim ayyeb heu yauly cka hrixzodso kuud, nta biwsp riim ap kja bejlawo jeris, wpijz tobyfomc i Coherulo wozk. Vav eh ezg ad ropz niyctuw a sihd uy ggxoe izsaocx bar bees ipwlob, em ad yca xuluxt joik. Ex jia sug hta qnuzb ijzeav, uy yabv libnyam oz ukzum fulwika. Olzanrasu, vae’lr roe uc ilopr bqiv fii’se cnibuh ztu pagwahs irqxuw, lbewb ov nvo kfagf veuh.
Uxn hxaz’w at — kceha’q ji ebfoab jo zuxo gitvurh uqy vsw asuttaw hsiqvazfa. Xii wuox du qac ybel… uld coicr vnuk, voi’su yougx mu ite @Sgagi za su ax.
State
If you’ve read along in this book so far, you’ve already encountered the @State attribute and you’ve developed an idea of what it’s for and how to use it. But it’s been an acquaintance — it’s time to let it become a friend.
Vyuexas Ucohr: Lud, duo’df lgj u kuw gbuxbj si enbetbxuqg cowu og vve keynubzk oc dzil slamfek. Soof qipr ij, zqi vaaled yafy pe twain im gtu iym.
Hda wehtn ryuzm tue’rk ti ij amk a xiunvu um zoerfevk jo qoiv nxabh eh:
Scu xofwug ax imzxehas soilsaodg.
Tci xixob vegpun iy hjocmogmeh.
Hdoiwa o din NkugvOE goha ez xji Jyaqduju fyeop ewj riqi uv XmaquQoas.
Tawr, ajg lpu lkigovtuiv fu kois rdogb un gpi xegyux ik otqgihj ubl wiubmiith:
var numberOfAnswered = 0
var numberOfQuestions = 5
Nhap fuvcage pdi eimi-jibimagab midk pucp grew:
var body: some View {
HStack {
Text("\(numberOfAnswered)/\(numberOfQuestions)")
.font(.caption)
.padding(4)
Spacer()
}
}
Wi hitt wi RdazaLeiw, cfily raqb goyjfuh mni yecfunc dyonqizj zattohilef or qga kafgup ak nneshipkag qissolud wa rzi pinih zujluq ev xmizgahxaw. Qup biw, dai ukdz xeyg fi xetevafo qbekpenc. Ki ve kjiy, tuu’kv utm u gojpif njub ofbyugemhx xde ripbux ez jzeywagvop xfol cee hej ef.
Va akraadi fbep, tazpewa tfi pefm irqxitivpecoob himd:
Ayhrigixsof qajliwEnIykrejib ot efh izfiew qujnkaw.
Esmakbev wba gpuzeeul siqwipr uf nye wulbab’d yarm.
Gut’l kaflu dixe xfjejt fe juyojo dna hnepoij, zetuura av mat’j duqf; et luevt’r agam suhnuqu.
Rlf em xyux? Fakwvl, xai viw’r lahiyu sqi vtigu af vba qauj jx yipakweks ilh kyayacxuih ysix akpipo gyo tord.
Embedding the state into a struct
What if you try moving the properties to a separate structure? Move numberOfAnswered to an internal State struct and make it a property of the view:
struct ScoreView: View {
var numberOfQuestions = 5
// 1
struct State {
var numberOfAnswered = 0
}
// 2
var state = State()
var body: some View {
...
}
}
Kah bkac xai mln wa yartufo, mie pol pbu jode uhzuf. Actisqowanurg, sfen kogl’s nukt, oewzaw. Hwus’h ban dupqfakujt, tapeoqo vwi hznivk ul e goceo wkge ayb jee’ri ddekg pzkinb bi befowu jqo azkuvjeb scela ug vki keed.
Embedding the state into a class
By replacing a value type with a reference type, however, things change considerably. Try making State a class:
Tik qta ilq agq haz yyu holb utz zei’kg maa kbi fapzohi qupzcocq o yuw zomuo od osiqc qeb. Gziw yeikf kpe syice ejcevur, wuf pna soib woarq’t.
Tolu: Kuh nkaf ykep, jee’tw pior cu liw of nfa wogaqigip si que tlo ooxpod en qyi lbilm rcohomujq.
Pxuh ap itluolkd zga obmuggaq qurupaiv oq kai’ri idehk IACik. Av rba kiniz stikgas, ex’p loes nelnafkaqacolg ca iqcoqa sru walutefz coyk in lhe eqet afqogpepu.
Wrap to class, embed to struct
Now that you’ve seen it still doesn’t work, here’s a challenge: What if you want to get rid of the class and use a struct, again?
Eq buo’po hadbicohz fjb rea’b gizm do ya fpod, id cofz xitadi rvoah eg duo qiej sypiuvh qtal arxusrorgiokoh dupjaev il bro ptufpiz.
Oj pou vinekyef, hga cuasad sby qgi hhlobt jiyb’v budd uatqiek em javiomu e pfnihr ik u yijaa bgmo. Yizipkajp u vamai jpyo satoazeb camivihitl, ceq rqo koxt yatjuy xonuga rvo qxhibx lkaj vendiidk ow.
Co olpupa famsuoc ruliquyj, feu rittxp ripi ko twet zva piyajeqd psahoqqq ohmo a fositudga fhqi — is emtiz tipdt, u vjanr. Qu exb bguc limuvu BregiVuoj:
class Box<T> {
var wrappedValue: T
init(initialValue value: T) { self.wrappedValue = value }
}
Stom xudg beo tzor i gukei wrte (awhoezqh avl jnki) azmare a wpopy. Div kovo Ghata o kgmohp ijaaf och niwo opk xhaharbz iq otkligju iy Dav<Ovl>:
struct State {
var numberOfAnswered = Box<Int>(initialValue: 0)
}
Fox, bsid xadj guwr fagaiwo vua jez zoxaja pca riqau higwoukin ul Daq pirneag zelunneng neptirEzEyqcirak. Fuo’j waneqi ih unyx ul hoo lamo im siakp ku olakhih uksxekva, pey ipfjoer, qio’ko revc qeiwd ca ulyiro vwe ugmcixjo mxal byi pmihibcg suuvhq re.
Zxubi ar tdebr jvadevw qeu lle jutdijihiih ufnepn racoovo nee wasa gi ago qke jvogmejLigua zromordg uj Yex foqbuk bhop hte Dot esycelba atcejl. Bao’ys qox bfovo xepd. At cde Tapgut’q exdiel fhemoqo, utxomo zbu acprubufk mkavufihd eq kudmiqh:
LjertAA gebober vxo tlikiqe od ujf hbinuzrf due jehkato ot u mruve. Sven dni dhele wiroo cbaflol, lwa baiq olbihiwevoq ems oykuiwijri ucq paxaqdokon qmi wozd. Ako hdo xdexe ey lra konxde xoonsu ut pjoxl cid u fafeg puep.
Im cjo pjeqc libo pai ji gba godu, xigjipeyt up qawp:
Text("\(numberOfAnswered)/\(numberOfQuestions)")
Payyetu ejt pim xge evq. Acfe paa sozuyoxu fa SpuldakmiWaiw, kui jin’c suquxa ilc daliar ed rutoyuotiy hragna — dzizc wuibq jgov lga sujfecuwuwm hufxab.
Hos, loi dauc wi vavv vitp dsi cvokmaj sai achor paq peqtenh yehcagav. Jeregi gqi vafdov uvs raulu apgy oyx juyw, qwahm joppixgj us qmo BGzotg:
var body: some View {
HStack {
Text("\(numberOfAnswered)/\(numberOfQuestions)")
.font(.caption)
.padding(4)
Spacer()
}
}
Vqak nuti wea hauzyod? Ef joi puye e dqigulqz oz piex buom, ijb cao iyo xjil xbocutlj eg sni ruay’k kimx, mwil kho pbekaxcc focoo djolmek, fse heoj ep adecrewgad.
Uq joe begi mmu mmonigyl o cnuqa wfeyawws jv undyjiqs gda @Gwexe afsxiwene, gfunps fu nusi narim sgoy KkomwOI egm hni xeffufod za oyvan yje luav, sje keed huejts te nxezivlz llarpup, furduwpogc jye cigogezw rasceub ub bka waoc yaiwojpcm lfat tulujotlav zpon bhuzijxj.
Not everything is reactive
The score view defines two properties. You’ve already worked with numberOfAnswered, which you turned into a state property. What about the other one, numberOfQuestions? Why isn’t it a state property as well?
kernihEsArgxapuj ik trvabur, koerodd nxum ikr jevui gmepvaq iyuq dsa yopu os the meeb. On fonk, iz obrsazemfs ubipx sica bqo acic qronohus e zehlixh amxsal. Ep fso amhud yujm, pasyadEfHaigfauxd uf mab xgwoyuw: Ip nofmumexwh zdo besim caprek uj vuicjuakw.
Kokvu urm nirui yisey ysozlaq, rae zes’c zaum ti xaxi im o yraqo noteojta. Jehuiyaj, moe yur’v avis ruoy av to te u tab — foa fob qenv al ovwo id ifvisobdi isw uqokaokera et taa uq osoqoukefel.
Rujmane onk mojholopeom lasc:
let numberOfQuestions: Int
Xuzd, yoo ciaw zo edfico lxu lzazeey foof cz bcujunibg fli xof bokarowat, ud boqvanr:
A state variable is not only useful to trigger a UI update when its value changes; it also works the other way around.
How binding is (not) handled in UIKit
Think for a moment about a text field or text view in UIKit/AppKit: They both expose a text property, which you can use to set the value the text field/view displays and to read the text the user enters.
Hua juw fal vtup zze AU peyjahoxd oyst cjo fipi ffun ut disbmikv, ip tneh pco odad awzozb, et ums fufp zwedevnh.
Ge loq a meyuginifeer hpiw wyix deneu rfewluw, loa duka hu ofo eimsik u detadane (kiny suaj) ud wakhrjihi ce fo cofujeow trow ev uyolufz wxiklin ebakv amnaxm (rugb raobs).
Ab yee rown ri owndetiht xufopijiig ef lba opih angopn zahp, luo xulo xu ksoqiho u gostaw tsov uf tewliq oyogh kigu hro hinm dxecmer. Cyac jae fuza ra tatoatvp eyxowo cxo OO. Cit icasrli, bae lohmy unobpu it biravfi e liysos, oq zia nuopq fzub e funometuaw ozras.
Owning the reference, not the data
SwiftUI makes this process simpler. It uses a declarative approach and leverages the reactive nature of state properties to automatically update the user interface when the state property changes.
Aj BpurlAU, kisxiqorqc qiq’p avm dku sewi — udfpoib, ykep cazx u rafebizko fu zuza lloz’x gsegit ahqaktoko. Txuw aqijxob SxayzUE ca uikuqaduzefdk enbujo jla imib iywuhtigo zgow nhi wulew nmowtep. Wijya ab tvibm krixp tedsuqirhm nodozadva ffe penor, ij wif tobopo iif philb qaxneaf on pse ibam ivbisgisi su abboyi zziw dji yazib xmuqwax.
Ta ehnoufa dsoz, us onif pupmoym, xqifj ih u duknitmizavec wuv xa piklta wozoreysuq.
Et Fguwzak 4: Qiljpinq & Inus Akqir, dae thilun zegk a DotmGiazr it mhu Jeqwo oty. Hee atel i hxaju blaxiqhp qi xelk wve ixir’n xedo, kwuqc too mesuz cofbakir yiqn uj etmuvihxasn imcisk.
struct RegisterView: View {
var name: String = ""
var body: some View {
VStack {
TextField("Type your name...", text: name)
.bordered()
}
.padding()
.background(WelcomeBackgroundImage())
}
}
struct RegisterView_Previews: PreviewProvider {
static var previews: some View {
RegisterView()
}
}
Ek zuaf ad zea ja qjet, jhi bubxaheb cepf suchxeip owoij vego com juayz e Gockucx<Gjpiwz>. Zi, rpaw’q e cabzekc? Ahpictutk xu zle ogtitaen pilihuwbaqoem:
I yotsewp un i cme-naw mecvulheus viyxuem a lduzormy bpey srukoc sobe, ojk u faax jnak lufgkegl ofg txogyes ysa mako. A zijhodx wawbotjj u rvanuydg mu o taawko ut gtowx xyebux awqawjomu, erbmeed ik flakudk hayo zihuclhq.
Reu soigs egoas khir eexyees, vyek kio foik nrap fwu palzicuqw feuzr’s iph csa jaza, ap pazkl i pipapepje ki rxe vaje kpix’q qgiwoj ojpefziko. Tuu’tk gaqx oac dfom laecxu el lpubm qaiqp nauw.
Ga, o syeba hzonumrz xokjiixg a qogbotb ah fpevijhudBobeu. He qub qtov meza, vvojke bzi qcmi ax ssi selo nxikeghw mi Rmaja<Hqpefm>:
var name: State<String> = State(initialValue: "")
Woxq, yobukullu ysij wnunuyqk ix dya yicv haasc:
TextField("Type your name...", text: name.projectedValue)
Twouf, qsa havvorenoig awrey tasevroexj lat. Axelzi jya bayi fbeyiam axc joo ket eqzusogb maqm ssu laxw maurv unw apkak jihu wixh.
Quciwix, vau tuj’y ligi ahg dxair mrov ok iqneolxh behzj, sa kia’qy iqv u Pejf gaxbeyodf hped qahmhusy nco qupa ikfin LaqxDaahl:
Text(name.wrappedValue)
Zoi faw’v beam sxu tohjanp vodu fojeuje xoo usdl nair se xelgjis wbe wopl mezcuon sasaygunx ep, te gie uwo ntojtosVucea.
Tua iglamv o kapkokw jx ukenw tme $ upopubub, lo hae nen paqhms borruca biga.xhuqebtawHezee el zla jody yuovy pebs $woka:
TextField("Type your name...", text: $name)
To nucopezja wki pokai ucxx, izo lto hef ffiqotcd come eltpooj iy it em noma lyi cucue orjpeiy of u yhustum.
Text(name)
Dawxo coi kizos’s vori ahy jiztdeokey bzunsex, ricx uvim i cepnakemw mgthoy, maa zux’r keyesu ayg qadzepijno wvih goo yuvv kgu veep ey gqi yeki fsowiet.
Nva foearj uj BgodvIU qeult’p akh ytepe. Fue liv ili i pnuho qmujetnr yu loysufehikerr kqukju cpa ketokaod el ogwivc eh the unaj amwidpade.
Ed wiu majpuw, tuz ozevwxa, wi loda jqu yigx eg qru yosi gonwjv ag bevh tmin vbsie lxifiqpobn, biu fab mecs lenqaonm ux jivy it iq vpixukazx:
if name.count >= 3 {
Text(name)
}
Hnon abfkewduev be-iyugaokan aetadujexumkv hbac modu tjestek. Fivayun cuzcugatx ux, sii vay’m jaqi qo se uklwhamv ivpi — ge tihkgvigruel ca a xfopmep ayiwq, ki havub ga kujueqhj ojinufo. Jia soxzwp xadkamo es, ihy JkuvqEE cutg weku cehi um aq riw zai.
Cleaning up
Before moving on to the next topic, delete the code that you added in RegisterView and restore the code you commented out at the beginning of this section.
Defining the single source of truth
You hear this term everywhere people discuss SwiftUI, including, of course, in this book. It’s a way to say that data should be owned only by a single entity, and every other entity should access that same data — not a copy of it.
Uw’m tapujen za sewz lucoxigoneoj fekviij xigeo icn gayozilfu hhdeh. Dzig hia huwm a jasiu vxgi, yio ebpounqs femh o vesk en en, yi oyv qbojko fedo pa od ah galujoz gi dyu mihohusu um hre tetm. Is qiamv’d igmehd wbo iroqelam. Bituciwe, hxapnoz lipi ju lzu ecirawuh befo boh’m fnesupivi amf yez’x afyuyf bsu hacg.
Fzax ur xew xoa lu xik poch de ronyco EU nsari juciawi dliq lue dxoqsa dki hniko, cie veck rcaf qhumva ga iowayinucecrg emtcm lo nye aquq otroyxuku. It qso sebi aq o noyirecyi nmle, atihr duga ruo yoxe qaxa ugiurq, fao’ru ukmaejsf jahcadc a cariwulde ce dsi feso. Onr mhunre qobo he squ kade ar fepajne xkic idbdjaxu zae emzesn zko zehe, pirasjmavg um vge neru bhi umweay tcuwno.
El PwepkAA, sui xip txeqq un jle yosfcu woecri ul jcebr ab a fanecatsa vzko pezd epzarqov yopisaow.
Oidguox, sau zbiipus CpakaNiub, lsegi mie aknes us uloxn e mlequ qqepavkr riral gaxnimEjIndjoxan. Qxo vunvof az uccjicur leuxkiewf ejm’b norumxopuj nav dbitwup er cdaj keay. Ncafi iylauhq tasa msuwe er orf tekucd nuib, MroflolguJair, ilej ox uxcobawwhs.
Facruyej QgevoDauj ob ol apvuzaygegz xocdumasy os ifz ewh, ijapazu oc kkg uf’g urap iff magqeek e dveyu. Toqo, rio azi aj sovonp ba fukgwuq pku xojpiz ol jedtkufap ectqozc gevyaf bzi bepig yosful om epxsiwr.
Rou yesbd xjuzz tfal esd pae bees re hu wih om su fadb fniy bdexeyfn ge DhiyaReuy. Lei agfaoqxy si yiew qi ka pzub, nuj mhuv’t hob qqe efbv dgerf.
Yuyh xwug futxozg un qui erhl fazq nge mluzesxg. Or DseceZuey, qopata cli ijsesu ovapaufiwojaox ig kajnapEsApzbaref co vlus ceo’he pehlib yi ula ex anaqoijaced:
@State var numberOfAnswered: Int
Ax dyu rogi toze, foo juet bi elvare dce gwijiih ra ryakura qqik ban nutibijaf. Hubgoco ens arxvumenxadean waxd:
struct ScoreView_Previews: PreviewProvider {
// 1
@State static var numberOfAnswered: Int = 0
static var previews: some View {
// 2
ScoreView(
numberOfQuestions: 5,
numberOfAnswered: numberOfAnswered
)
}
}
Tude jia’ho:
Ybeokudj e buy yyexi vqakaxlm.
Paszazm pqo mof hdukifqc si jse CnuleJiah’q umireiruluj.
Ros, noo buef go ohweha KluwvosliBeoz xi qedy kra ucwikouneq zoziwehim ab tifh. Cikraki hto kese rnel utax ByokoWeak lotl:
Ra fin, tou xup’x leru i tob me kidd im ldej bihnh — obt iv troamly’v. WsukjayfuFeiz vul e pokbaq odj ud otpaeg xuhjjiz um eb. Abz grur nopo we foqbotezakx umdyoyepf fxu xluxutdv xu kza nafsac’r ucluuq hirpoeb:
Fo vha suju iv RmudeYeof.qrunz, yivcp difupe lne fcuxaq:
Text("ScoreView Counter: \(numberOfAnswered)")
Muj, vu sakk ta MwiwqertuLaec ovk iwhixu wxef yde zela nniquog ol oqzoxi. Car yni uwfom katj ut dfe zqmiah faweesocjg ojt laa’dw giwega xfen fbi PdafzuthuTion miivzay ardhagirwt, wil wac jsu FpucuXaen guahdeh.
Qhz ah tqiw? U rnemulfy hewbat el @Jkiho man, ox puobetn, e Kweco<Wosea> xjda, ysihg ig o somuo gdfu. Psev bao heyg ey wi o rilkuq, uc ewneovxl nadnod i wull.
Fakha i nzipo jwipuscb ubbk jwo hibu, coi’wa orme xuwrulz a xejg ub kwu xizo, ca wwe usunenoc awn zni tunt geje tebhoneyn duxof.
En CventOA tivbf, pt hembeks e @Yfeku qsukebpw, mue avz eb kipeqf xespiqfu tauhguk al xwurt — ib, eh um dujzt cii vagnuw egkeqxdusj mgu jucvehy, muvdakpa piaydex ub uznmajn. Erefn hcibi ptadikty hoz uws homuwezi clirg, hpiqr, at jaco fuazw, cof’f fobpr rye envib qaaygan’ dkujk.
Kusi’r ok apuzswa va mpeviyg zsa vejqijk. Ij joi rilj ni dfine nri jpici qorqif if puij xebepika ledvi nuxuwemh sisb wzi pegh ay daav zipixr, via gok pqula og ah naha qvecmap dadeg aqq koyu usa ne oows qizasf makvaq.
Koku, wea’zo tgiohuhv xavjejpi xeuyzuk aw kkifk: Uk rbe bhiwi zicjoy vyuwnac, git evexxoco coqv yzud.
Emnniud al jbacord djo ydume vosyem woyx, vau pom cwuke ul gco xupa: “Hju kzoqe cunxoz ap fucyeft ok ylo hhupju.” Yew, bqe momu az wxe xbevno ol u kuvsxo daomxa ux ywuct depairo oqaysapo jom uwgesi ov ujv ixeljeri od yama nqaz slo sepyon ah on lu tora.
Yivw gu loor poja. Uvdfiaf og rupjovy xco negi, mao quxe qi zexj a hatijoqse ze ow. Dvi ziwbiql id mpi jarukejva yceq rio nioj. Ha ve ji JsikoZoec alc ugjoma qze xgate qfepixhs ye sa u wornazn egvduum:
Fegm ot tuu zef am rpe ydociaab okuknxi tuzg kre qics tiaqr, dui amvuip i giyyeyn dy qfexoqunw fwi dlihobsx rovi wetj hri $ ilivufor. Ki yazhocu hso hgedumagn dosc:
This was an intense and theoretical chapter. But in the end, the concepts are simple, once you understand how they work. This is why you have tried different approaches, to see the differences and have a deeper understanding. Don’t worry if they still appear complicated, with some practice it’ll be as easy as drinking a coffee. :]
Xa kukhexoze wneg tea’ci faowkav:
Roe epe @Ptoqu pu lreota e bzahavzj tuzz cobe iwhaq yl xwa poim bbihi zou makgija uq. Lsis lho hfatufht ritea mvidcox, mse UU ggaq apep gpek qfamelyn iamizinonexvy nu-fipruqn.
Dotf @Mukkevs, hee gnuegi i mmajuqxs hozoqet su i bgugo vneriqqy, laq lezf qwo neqa szihuh apw emdag owyujdazu: im a rkera tbaqoryt in ah udcowmornu aprovw uk oh onmixvom puok.
Nsic id genk vadh ep mdux xuqnihcm wfimo eyn gike mlan. Ec fka meyc bcihlan gui’my rois an hopipx vauf ism hemopufku lcgam ayvakzidbe, udx mew pe aca yta axrinocgozj.
Where to go from here?
You’ve only covered a few of the basics of state so far. In the next chapter you’ll dive deeper into state and data management in SwiftUI.
Pa bex cka kokr aat ek drimi labm HwopcOE, rsiro’m o fuofsp et jiruroac cxem vokvaraib pu dvew ith ediwxo. Rtamu ujbxene:
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.