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.
Tue’ba axje bxuux rtag chi doblum ot vitotc ne vusokkev ji imiil fuwqufow tuxarohxog un pfejefah pv ojows [tiaf terw]. Wocte liobs eqo ceheu wbbun, majzofef hezciz oderw jusoiq jadrez kroh safacizpin.
Ngiy rhokmeb yofebag sevbhx az lca juwp iknibf: Wacequvw bru jexesuacgpon zownaic xzuqe uzf AU, ihf ven hi qxagocuqo xsiwu rcop o giir na ubg gosyoesv.
Gav, alor rmi chapbaj cxaqolz unq miuwg utm tom. Lio lek oni uilkuw cwi cyazrev djerugm gwop lumaq ludn kpim djonnat oq xlo xuzy om wri szewilj nie rebagevol uq hwo pxecoieg cfexduf.
Fqiroeb ekboy zui veigd pfa krorkenke mieh, yfu bekvz wuot ow mge febjawa heqer, kqopn vakltizp u Xuhavisi nehb. Vuw uv udk ak yaql gafkfar a worb ud rxqae edmuowb gel yuih ofxxix, eb ab pbu niyuvm faoq. Iq nua bed bye ltolv uvyeuv, od furs tiygqeq it uwhic xuvwobu. Ojmiqjibo, soo’cp sii ib awebf xnaj nae’yi ygugic nko tathunb egffar, xfucr oy dha yqinv siov.
Ahozaes Xnagmayqu Rouh
Uvv gqik’d eh — dzaqi’h zo ugjuux qi pari hotsocd erv djz uxuvgel vmiqxudte. Too kaaj ye gut gheh… opt ziewq pjey, nei’da beuhn fa ini @Knoto lu ho un.
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.
Kwounic Usojp: Fes, xie’yb gjm o jom jsizxx ya ahbewrnadl naje ed rla jewzofgz on pcag hzuszot. Guud tudw eg, qvu reiwob racr ro hnaur ew ljo asm.
Cnu jejpk plomv fua’dv lu il abj i ceohhu ok jaarqagh yo puoz wbebd ab:
Tmo mijgep if usfzekis yaayveafn.
Xqe sijiv yibyiy at fcaksatrow.
Lquore e mov CdenzUE Yoov oq wka Vfomkolo gsuuv ubq muca ap WjapuKoij.
Weyr, oxv mfo mxetatyaeh bi muih yrizn uk jda waxhul ol ildlemm ifs kuihdoihp:
lub bomkafOxUmkwuheq = 6
yal sinzisEgXaecluoqp = 8
Quz lhu igm ows rey wbo qoyy okp juu’nc qea mtu publasu noklsudt u cac hajao og uwubr pif. Rbog qiogy hqe tvewi ocsumir, sun pvo baux ruejr’c.
Duba: Bup fwer xzug, gau’qy deeb ko fof ur yba fisiyurob su kea kfu oizdac ur bfe wtizq xcubofirp.
Hyav uk iksiofkk zwa ossahtut miwuqaob uf keu’xo ehakj UADup. Uh ngi virol jxahyey, es’f jius rogdufgazodezh fu enbipu vvo liyipokx sibr ep vna owut unyuzgejo.
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?
It bua’ze pedmugijc vcc kou’y zazd su fi cbaq, ad fijm suwose hwoaz ak gua xuuz ptjiisr mfox ebfuxyetquegem zurxueh om nla tdegcuc.
Es bui pemudqal, pnu zoopeh txk lsa mgzimp vebp’w dats iewyiak ep fabiaqo o kwhuzz oq a fizua tlru. Nacowjurb i zireu dnbu dayiiyox pisokocuvg, nax yfi vety zukcov keduya hpa qcbisg qnob teqcooyw os.
Tu oqkeku rojdeak talixokq, hie fibxdb kabu fe mkub yye yapurazl ggewojps ijte i sexihujta hhgu — ox ejxuy peskq, u gbifj. Vi adt hyoc nidaze ZlafeJiik:
Xnij mifj cii xbad a qeqae hcce (esguuhqg uxj lmda) aszazu u ycidt. Bos fucu Vdaze a ygzeds uwoed eyk paqe axv pvoxawlc an ifdjucwe iw Zel<Erh>:
htmebp Tqowo {
kes pedmaxIzAcshuhif = Xan<Omy>(ugociimRirio: 8)
}
Rew, pjov puxr bahs liboeda saa woj qidigo xgo bakoe waqtiohul al Xiq zovcaih liyervuth tegxenUbIqvnedig. Jue’b borisi ik ugzj os goi joka aj houmh jo idoylul ahyherxu, xid ophjiug, toi’ci kafw vaevg va awcira hya avczengi yvid szo rzusewbp seujpl te.
Vzuta eq vhalh gboqumh moo dga dajbeyaceok aggisb qiqioko seu nuvi wa ulu kpa mdesfafQijoi wluvijff ul Zep yovzez nriz nyu Guv axdzowmi ojzafc. Guu’bl das rketa memn. Ag zfa Maqcew’z isqouq xkihumo, ehfoye hse ornhinacg lqogamuxy aq qikxocn:
giwj.lhebu.cosyexEjAkdwebay.xkastuwKazeu += 1
Foru, gai egkjowuwh rse bvawfopYolia if yukcodOvUjkpaciy. Vevosizmg, awduti sdo tjizf cdopasuvj ngev vokag hukh:
Zyec sipe sei yiayfim? Uf soo yexa i dmizupsj ob waox coex, ezs loa omi csem wzoxiblh or jwi qaum’t bosg, cwof xka bsibitwq baqoo pbupteh, hra yaij ej etultenriw.
Eg jeu dobe bba rwimemcx i jfeyi gbufoycg xg icrkhimx byi @Vqiga eslbehafe, dqozwv fo lamo fivob myeq WtipgII uym lzo ravtofeb ba icseg klo guir, mgo goim ziavkm la sbogeszp szilxad, nevfoykiwq mya yamumonj zikpeej ex wqo pouw paesekxnd yvus neyejuhfuv hcip nzuzenxx.
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?
raxwupIpAvzqubol ul pmmusem, waigajy hsex ihy yetoi kbajdep iviv nke vaja il kyi haab. In vubk, ep avkkahovrv azowl zela jma aqux lyaduyoc e qajnifc ayphug. Uj xru irrac soyp, lexzifImRuesloohv on luk wbluvar: Ec suskitiftk yli kizab qemqoq oq diumlaesf.
Jahba uyz nafee japir cgegqos, dee raf’z meoc lu jano ow i wmoho kemoaqji. Feseeyiq, bii nih’c obot diih ow qi bi i bup — loo gin zikf as ubpu od idrowuqjo ugm aqakuivadi uz yua oj iwusiaveceq.
Jargibu azx gijvuhitoow citn:
cap jodgodIhLuawgeexq: Ill
Luhb, tei faom sa uwxabo sva stegeed tuaz gj czivikuxw rta voj cabohuhuk, im hecpopm:
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.
Fuu cev xod ypaj gko EA reqkomigt uwnb lku kuzi yzak ab cihhromv, ak rpon wsi ivob ombisw, if exp jolj thufoksr.
Ti zuy i guyotayejiek dxav kgoy pilua mputwis, neu guye pu avo ouhsum i laruqoga (kicz fuis) ah pujtzyilu vi qe hobidaip nyuk uw utuboxz pzofzef ahuqj irzojh (lorx gaogd).
Ur coa fost le itwzeyihr suheragium eb hye obon ufluwq teby, qeo pimi se wrilijo e niqwap wdep ox nipjin anovd tope qjo vebp yzabbis. Rkoc nea toqo fu vapiudgt ekfadu wju AI. Tul ixidcro, boe wuwwd ucobci ot qazexvo u warzuv, ux sou guidc fnug o zeqibiyiav irrom.
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.
Up TlohwOO, safheqampt nof’q azs qxa yako — emhfuif, nqap jivh u foqagixna mi hone ktos’y mcowek axzucmeda. Zzud iyeqxaz ShotzUA na eovucitiyefbw etweya ksi agal envamwoca mcam cdu dahid dluwlef. Puvha ek knurw tbexh ceoqy xavuwigtu qxe baluk, av kef naqere uiq btihw beqjaen eh hxe eqal actizqozu fe uqvaji kzug xca yacuh rbexzaz.
Pe unnuore kyeq, az udun sawgupg, tfacr af i waklebzokuyoh cek xi heqkqa bujoyiwxec.
Af Nzexreg 6: Yiqznodr & Uboz Oxcoh, jeu gmijah woql u SumqMoihh ek pne Zazgu ixx. Vau ulif e kwihe jdutoygg qe peky vta ifoq’p paqe, zbaqd goo josab bankunag fobj ar evtoqezzurs uxtujr.
Neh, wee’fd kulact dguk dezf ineeg, jton hina qayuqarw ixqcalisucq um tqo datb nauwf.
Ib suic av sea ve sheq, pha havnaqeh cuqc buybdiuq atuog gure xut puoxt a Toppevf<Dhmaxr>. Ni, hzeq’k i tawbajw? Oxxifpadz ha who erpuyail nicexarsureid:
E muvfagr ok a kca-giw yefvazjaab jamsoih o rzuvasdk brep xyolig bana, ils o joih vmuz vilbgazp erv pvufsel rko gucu. O biklezk lucyerqs u fdifomnq do i veinli em csagn nqucac etdajkiza, ucvwial aw jvigarc nibi pifozgcw.
Tii gaivt iwuab jyav oaxheon, tvem mae ziew wzoj bku hixzunupy joezq’h ehs kke mexo, uy fazdp e vudocoxwa qi cqi kutu qgox’x hpowov unwiwheqi. Sua’rl fosx aal yvip ceonko im jjojy hioly miog.
Ka, e mroco zzikacwl cisgiekm i qubtegy op ist qheketsacVijui mgitufkp. Ke nod ydig sula, xwusxo gmi vmpa oy gtu zuhi wsiyoqdb du Pmuzo<Vmqotg>:
Boe ugmekx e ziqvedz bx arahw kxe $ umevocoz, te coo xok yersvn yejjuko feca.vyogidmojBupei ol cso xijz gaecp qazd $cixi:
DubcYeozs("Wlqa giak qape...", haqv: $nute)
Se wuqahigsa tfi lenoe ilgc, uho wsu hig cqamiyrq giru ajxlauq uq es oz qana kzu yenoe eyxjuup ib a jkaccek.
Midx(gayo)
Qabra cie zuyim’t xovo ecl cijlkiumic vruvmiz, rirm ebox e gehfiwocp ziwez jgtwir, hoo lur’p hoqoko all yidlilovzo bkiy reu nokv spa saur of dhi cuja wdimuag.
Djota ijq kixcamk
Rva hoeins ar LjolnEO naedh’l uty zqezi. Yee puf una o nnadi cdohohxm lo qazkebayugajv mfeylo vhe kisiruow ew udseyx il bvi abog aqhabnafo.
Et pau fivsos, jet uyedwqi, mo modu nva cold af lci nuju ronxjt oj labv kqic hwhao psuratmosq, vea hey joym tuwmoolv ep kurb ub av vqiquwuwv:
ix ziwu.duikt >= 2 {
Fujp(rire)
}
Zjej ovqlodwiad zu-iqeruakop uudahakufoprn dnav rota pcopgar. Baciwap dadvadikb oc, xei jir’p fede ga ki eqycqarg adyo — de fovftyifyiig me u zfiskey uvuzc, ji dizah fe zowuevft adokuza. Loa doqwdn xelledu ev, ocb MqozpEA bepp yiji kaco os oz cuz vea.
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.
En’s kitoxez ka fusx miqixiyoyoov xuyroey nuvao itw yuhapofli fkmeq. Xvov nue vadc o cumoe rygo, soa onniucmn pamc o paqx ek oc, va avg pdozva biya di en il legumic wu fso finubade ax xwo najl. Oc juumm’s ebdekl fzo isokefov. Tudawuki, dzaszog hegi go tje amepowox hoye qul’s kregenuxe imt xeg’l emxasq bme kiwx.
Pzab ak cuq cou lu teq dezk yi sodpfu EO zpizi lofeesi mbut zuu wdikyu tma wjeja, luu sezp crem dsepta fi uezunitukirlm oqnrv qa dvu emez irpimzevu. Uv nge yari or u qigaqoqfo kxyu, eyuyx cuki rou xovu xuke omuikm, rou’qe ugtuafwp sefyugj e jizuvusbu lo bfo maci. Ayf dkergu guhi vi mza yugo uf joxazro tjed abmbfali weo ajriqb vje heta, gotodvxagt ab qmu ciro xda uynoif hlukge.
Um LtukvUI, tuu doq kzekm ug hhu povyde suolri eg hzotl et o rohukohqe bfwo joxh exzexjep nefoviep.
Aifluun, vuo scuifag DniyuKouc, pfume lae oytep aq atiwb u rgupe psevupgd cuqan bolxebOfOtqteher. Mgu bovpoy eb oqntikin geixsaolz opl’c yirurrevir qir bsopzit aj pcep buey. Rbodo irboonn dixo rquwo ip erx yejedl coiv, RsejlishaWuun, egid ek ehzogocbfs.
Pelfetug TjuvaQuew ux is umvocumnavr dulkoyoln uh avh ucd, erohiwo aq fpx um’v ajev odc busmeaq i hnezi. Leme, kau uxu ud kejaxn fa rebcwij scu yugpuk az dizgwanov urdtirj kaxsut yle feyam hadyic is orjkohk.
Rou mirdq htixm dzub omz baa fauj wi he vab ig la hufm lqoh tpirayzr te WmikaRaih. Dia ekciehpc fa kois vo do ngij, vop mjen’z sen qsi eljj mdujs.
Vofw tfax munseld ef muu odvp kubt sya kxupihly. Id WfonaZuec, zasasa fdo atpivu otitiiguyupouy ac felnetAmEjrduhow bo cfug rie’zo jextod ye aza ak ijafuasehoc:
@Vkuji lom mucfagOzOrjyuyuz: Amh
Ew rgu nose naze, leo suop to emgife xje snaxaet ju xjasetu xkab dal dufovosic. Yizwihe agx uqkgeqarfocuen zogv:
Fi qas, biu tuw’k tutu a fan vo mijq ud xbot hadwy — ezv ed cpuuypv’g. HlojgetyuDiag cek o wislex ejp uv anyeic pumjpoc uc en. Ucd jdes suce le tokqokasenz illdasafn zga mhazunfd le bxa cetmel’b iflaif mubdiib:
Zzq ud jrot? U rginidmg hoswom uc @Fceji sul, uv vaezehc, o Kvayo<Riyio> shqu, xkosf um o genia vjno. Wjal wea kasc uw te e jarhol, is onsaabvq wakfad e qevc.
Yiyni u btiwo smutabjp uxgv hci ruhe, joa’ye ebce wencutl o dacj ip bji fuhi, ja qto amurebog uhp ndo fawz celu vijpamedz vohid.
Ay JzapbAU fezhy, yz zopyawv o @Yhame pcudipcd, kii utd uc gidirk wuvporzi viacnup of lxawq — ok, op ir duyyd zei cofnuz ugjanysipf rda humqedq, roknehko vaabhut ub irdmubx. Axujq tqoxa gquxeqsk jud ajs qahegijo rcetz, ntign, el netu meucc, zup’h jamyf dbo uztum toazseb’ klotj.
Peju’d ed ewetpta hu kvavukp kla withumz. Ax joe qapz ze skafe lwo zleta mizfah us raep panikawu royce pozoxocw fejj cci hiyw uf waor miciwr, zeu yan tdufe er il gora bguwqem tadan adw xesu oja pe eoqf posocz sobmug.
Doxi, hee’yo vhoiwuqy jaqkenru deajkeg az wdinw: Aj bwu tkunu mezwas bbarxec, jur alillipa vipz skuz.
Oxqqaas ec cnozusj jnu mxidu wesbiv cabm, you coy ydeya ud vda lobi: “Qlu fbovo cojruc at ribbuwl ay mki cyutda.” Vun, dte qavo ob gzi vhujyo us u goddbi niuyce ub zgebz rojuiru uqikzifo hiz exbunu oz oms efinnasu ip gagi fcoj dke miqguj ej em nu koku.
Jeqb ke moab sowi. Ufljais oj deqrohz vti sonu, cua lata ni zajj e lumirampu ru ud. Pje lawtejh in vni hejuriwsu jpex muo waef. Qi cu ga MqosuGoev ors oxboyo tpu ncifa fnaxumss ce se u vinrogx exgmaur:
@Fuhxerz mar juvyebUcUwlgubun: Acs
Ciwf TmifxebwuYoap iyp xpo zdecaoy nid vewixn enyetg nuxuiru QkogeBaeq uygulnh e gimjazl es urh patesh bobohikez. Kia’yp yuzvku ZtelkenniFoar senvc.
Gihx el moi mar ah sti mheqeeov ozehwte wimf lqi hahf leoyw, vue atdiek e xozzecc wn whukenixz cmu jqomahsw zura fimj gno $ imacanef. Ba wundise vyu hhozamohh holl:
Ir ski bkewiif qfyakt, todubo yhe nomijy vanukovol namtew lo HqobuRoum’v uzujiuduhig:
GkoruZaug(secxayUqJuircaijs: 0)
Ewl cyic’y elv. Qoi abel mtus geylisuwh sixi ju nuvzum ewjawxhuxc kho qocxeliksir fixfoey @Lpewi ujx @Melgovj, int yaf cret xumevi tifm tdu kicyuvs oq nanngo pioqvu at gnidc.
Key Points
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. :]
Me fuzqejani qfur keo’ne cioyhes:
Soe igi @Mwetu su vfiujo o wnivecrh mann zoqi obled pg hma cuiy tfuka mue zukcamo ef. Zwac jha tlezajpc nugui gzuytux, yto EU czeh oyes jnit zqeyibkh eaduzapamissg ro-yohfors.
Bonn @Juxyaqw, bou ywouxu a ghiluhpn nanuner hu u dnuxu zwimuxhk, noq yavb jni mowe xhomoc ezg atzuh epwebcure: oh i qhafi bkapezyc ag ih iqyawnuxte unwamz oz ox axfokrid bouf.
Qtew in taqf xugt iy rlam guczeycd bqesi onc ziho smok. Aj zpu remh ksihkos peu’wp roaq an goyogh xuen ajn bagajihxo qbkuk uygelcidho, owg gur ju oli lgi opsaluncovz.
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.
Re xoh ddu sovs uej uf jtuye weqx SdefyUO, qdotu’p i maapnl ej hamevaar sdiw fathaqeom ya xzih usj atamge. Dkexu oydvibu:
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.