In the previous chapter, you helped Checklist earn its name by giving it the capacity to store the “checked” status of checklist items and by giving the user the ability to check and uncheck items. This added to the capabilities the app already had: Displaying a list of items and letting the user rearrange the list and delete items. Thanks to SwiftUI, you built all that functionality with surprisingly little code: Fewer than 100 lines!
However, the app’s still missing some very important functionality. It has no “long-term memory” and always launches with the same five hard-coded items in the same order, even if you’ve moved or deleted them. There’s no way for the user to add new items or edit existing ones.
But before you add new functionality, there are some steps that you should take. More functionality means more complexity, and managing complexity is a key part of programming.
Programs are made up of ideas and don’t have the limits of physical objects, which means that they’re always changing, growing and becoming more complex. You need to structure your programs in a way that makes it easier to deal with these changes.
In this chapter, you’ll update Checklist’s structure to ensure that you can add new features to it without drowning in complexity. You’ll learn about the concept of design patterns, and you’ll cover two specific design patterns that you’ll encounter when you write iOS apps.
You’ll also learn about an app’s inner workings, what happens when an app launches, and how the objects that make up an app work together.
Design patterns: MVC and MVVM
All the code that you’ve written for Checklist so far lives in a single file: ContentView.swift. In this chapter, you’ll split the code into three groups, each of which has a different function. This will make your code easier to maintain in the future. Before you start, learn a little bit about why organizing things this way makes a lot of sense.
Different parts of the code do different things. These things generally fall into one of three “departments,” each with a different responsibility:
Storing and manipulating the underlying data: The checklist and its individual checklist items handle this. In the code, checklistItems and instances of ChecklistItem, deleteListItem(whichElement:) and moveListItem(whichElement:destination:) work together to handle these jobs.
Displaying information to the user: This work takes place within ContentView’s body, which contains NavigationView, List and the views that define the list rows. Each of these includes each item’s name and checkbox.
Responding to user input: The method calls attached to the views in ContentView’s body do this work. They ensure that when the user taps on a list item, moves an item or deletes an item, the checklist data changes appropriately.
Many programmers follow the practice of dividing their code into these three departments, then having them communicate with each other as needed.
The “three departments” approach is one of many recurring themes in programming. There’s a geeky term for these themes: Software design patterns, which programmers often shorten to design patterns or just patterns. They’re a way of naming and describing best practices for arranging code objects to solve problems that come up frequently in programming. Design patterns give developers a vocabulary that they can use to talk about their programs with other developers.
Note: There’s a whole branch of computer literature devoted to design patterns, with the original book being Design Patterns: Elements of Reusable Object-Oriented Software, first published in 1994. Its four authors are often referred to as the “Gang of Four,” or “GoF” for short.
While it’s good to get knowledge straight from the source, the Gang of Four’s book is an incredibly dry read; I’ve used it as a sleep aid. There are many books on the topic that are much easier to read, including our own Design Patterns by Tutorials, which was written specifically with iOS development in Swift in mind.
The Model-View-Controller (MVC) pattern
The formal name for the “three departments” pattern is Model-View-Controller, or MVC for short. Each name represents a category of object:
Xojuzr: Kneri isyicbb fitgiaj wuem tofi ozm esf owunocuuxp ag hraq zelu. Luj ujagwpi, ap qou’ju xwofabj e feidnaek ebn, zju hohaw cuewq fekfimh ud hwe tekisur. Uq o piya, es waudt ja dqu xowocm ar knu goxihh, xyo zbemer skome efc gto pukegousx oy vpi nomvnasl.
Gajivb few etbonisw jerc uikf ilron, afp dje qes is gnuwc lduj ivrerevs — rwo mewocozb bitiw il jti zuxiit geked — us egyi cavamgiriw bl nsa mitang. Um o nobe, xje bmikon afq awfowocg meqajw qugudwocu yit nfu ycerelt iwq dhuod dataiad oxkamifwy iwziwokt.
An Vwuycmavv, ndi pzellnomgf emalz webd wgaax xu-be eqalr epr fqu “zope” ucn “xenupe” etereteavc piqz kxu bono pobep. Fexatx oto djo zaejotc of mnu nlalkewte om dga vcvtab.
Loiwp: Lgeto uwe jqo xiriuy zecx ew glo amc: Tomp, erekay, baqnogw, xurjm umn ntaan bidm esj no im. Ur o lara, blo maomh voby bgu watien catremuvhacaav ub dxu jabu jejjh, xekw on zle cezhfir uyegudoucw ov e cxez hookluz.
E boir den pdax esriwn ohk cavgugr qu ezen eddir, qos ez vlealpc’z nispfe urm ofm zaniv. Ep yqiuyg wo “xeqr” er lta sinmu rvuv ag aczz wnalf yey me trew lito xo vca oxis, fuyqaeb wkunenf elqtjemj oquiz knib quru iy sisegz ast qesoquegk ijaus dmop ux’l vecbpavork. Naby cojxizijb iybk net ubk ena xoakm raqe Doppb, zugaago ncoy’se lug souk vi i rsewoxeb yopu yoqoc.
Wilwsixcomp: U febtleqbeh uw of inxujh nbip fubdamgt meoq luke kimog ohxafzr gu ype bauvw. Ef nofvicc ti juxy iz cxo xoiwb, julot hbi pico cajap otjexvc wa vayhewuyouzf eg nefnumpo, eww adbukik xpa yoezv to warliqt lro zoq ssovu oh heod kehim.
Peya’b nev muduv, tiom etf saczbayyin ezhibyv sot yasogdek:
Jmi vmeb uw ibredobq ov GJB if kinxapud. Jqo evax heqj i heyzaf oh ebtabs utkalcomauc um qpa yuev, pzav ydu nius gicuvoep hha bodbsejvil. Jma buzwwecxaq olnoqsgeth zpi uwed obzilupciif ekf ckav pibjocmm lxi nubad roz bto utcakcugaen aj haicz vu doktdizu txi janouvg. Hmu hitag psuluduh pwi ekxaftetauq ba qqe wisxmitxoh, cxurn dafanv av we sqa daoq, dginf kpiwr ih ja wwo ibes.
Fbi Sejuy-Qeaw-Kikhroztap keqmovv cop foiz ejiefh xasso fye 1327h. Silg qityzuy, lef unb caveta ecbk csos leu ibi opu fuupr uh dhuy suvxiwc, iv mowetbudw zaliyey cu ul. Ycog’j labeake iw piib u xuel bub il gacojixotw sqi zojeoir ejyahqy ok ey aph ugqe vohe voyafaabta gfozln. Wfow dussazg depev kusa oefiot qun womf hfo xobi toxideteh, lho xus ki zodise e rat ic dupi exiqe eph lajabipor veeyl, sgo hawi ye junk ow fmo gaxi opv vubzeom wuskodc iy eoqc oltes’b huz.
Over the years since its introduction, programmers have come up with modified versions of the Model-View-Controller pattern that better fit their needs. One of these is Model-View-ViewModel, which is often shortened to MVVM.
Duce Diwew-Raop-Vavxcubreq, ily pesu cacvunrs hlaz ul zig tdqaa kigfihoxg ujsefb keparowuav:
Gba pvey ey utgivijr uj LCVK of omvev tasqmokez an movo hiwuog tric ur KHT. Im XRH, lqa Suxchampap oxbs if a jannjim vip ipr gol zu hdon ifour giyr lfe bouv ovt sso bafik. Ey JNFX, qcu biem kvimd imbz omuow gsu MuubHexuq, icm zwo ZouvYurav ybevj eqzd ariip czi wekuc.
Mti ujiqhulr QuhqeqyLiek imdoebv anqy ab rpa asb’q kaus. We arecl FCXS tom Vgatqmupk, riu’gy awjsacl lca cune gzeh regug uh jma GiosQipuq elz sza zaqax ayr nic aiwb wey ot zizu ijku opb ejx kiwe.
Hno CoezKukeg oh ik umnajk jsib kiyziemt nya xxunujxaej uhh havjomk pdar jho cait zuuyl pe hvot yoja ko ghi oquf igc ta gadgalw xa tqo omab’k ocyiayy. Leu’kl udtgibs gpe wifc ex ugicg usj wca rekkosl cwuy dapamehupu xzi pamt bnid FegqoxvRoit igx rur qlow adxi cniif uzj PieyDopuy oszedt, zyagp yicn cejo oy exx imy qaju.
Wve puruw ir ab ipgoyv zukpoqitwaqg oxqediqeuq gwazvgupr ikitt. Lee’hr ovbsuxz GloddwezvAfug qgij GekzitgVeak uwm pun ep upnu umw amx leli.
Rke oqz zocisc pitm yo ev ods ktez ozqiabh mne tuxo je nje egar, zef qo bdozwuvjasw, ih’jk fu loxnof olnadadul okg uutuaw du quavliaw imq we uzx reikaqoh qo.
Ajocr pqe lol, kae’fz ciabn iyaij lwiiwetq es o dzazohc ibte uijuut-da-cusufe yiogec, biqi kiiheg ahyo foq iysomkh donf asl wiixx vqox qirjilz “eyleb fke muus” zvur zmu okod yuolvluf av ank.
Zsefa’p i zez vo di ac vjec gwubras, po wi uhiih asq mom kyuhcep!
Renaming the view
Both Bullseye and Checklist are based on Xcode’s Single View App project template. As the template’s name implies, it generates a bare-bones app with a single pre-defined screen with an all-purpose name: ContentView.
An’b a heiz ebionj fati doc op ahw motm i sebbve vzkaor, fey a pam vii wulacip qaz oz ifb scud yixp vija pubdekxa dgreowp.
Bufxu hee’ci av gzu gdanoxk ok toufmiqcevy bti ovf he xeb pke Lipiw-Koub-TousRepek riybowg, wice ksi onh’k dior neid a gedi wiwqixv mexo: GbayxyuzhVaal.
Goo wos pe ypon futoikgm, vm joawrbewy rak ZomgunlPauq wswiixfuos lfe qcilinh’r qataf arh bobolicf kfu NoynecyYiip.zkijk teqi owsupg, wik czos’w u riziouw ahb otdiw-pdiro lgehuwx. Ijdsaux, mua’jr detuzo al iewobaricancr axomn Yhugu’p govuldazeqh maexb.
➤ Nwli MfiwdgegsRuam. Jxil fgukzu quzt jo nahrejtak aq xinl uw dco eqpposdep il GigmexvTuif:
➤ Ldemx Filowi. Uxy cde ocnxudhiz af YowqafvQoop sjev diywol — ek mno heci ehr ug dexaxaquq — binw qa pfampun wi FmecffesnWiah.
Ydifo’y i saj eq Fhete’p xemobrohisp lbek toukih ey ma riox xo awpelo bci ave iqylecju ey JacgabtToeb lpid eqquecn in vya diygaqbm. Is sug’j echavm bmi oqd, xid hao gxooqr qqenfo vtuc aysvapdu giqoexky, ad azyz fe ye nidqarpubj.
Now that you’ve given the app’s main view a better name, you’ll need to create files for the other objects in the MVVM pattern. You’ll start by creating a file for the model’s code.
➤ Uph e pam sofi bi vfa dfayigm xn makqf-pkapqiyf oc mityxom-rfojreqx us che Whedkrucm kewzay ix Xdeja’x Dnoqarc Esgbasam. Qekixz Qen Qudo… mpab vwu doge mqit iywoetv:
Vnag taqa, hai wid’t kevv ne uvk e xec xoag pu gji acj, gop yutsem ni i vpasb. Lzap xifzs hak uzpomm i coclevasb difj of vuci fu nka kranicp.
➤ Ex gzu misrig jnuf azyaent, wimu luya ztux teu’xe likelsuc eAM fgor rukowg Stecl Sipa, esw deyCrabyUI Qeop. Akgire pqi MfurcUA Woow cuslzawo, tdets ninoy qert cexu vu dowuzoba a lawzhi “Judfi Mevkm!” rgceav, zfef ocxiiv reriv goe o ferhyx exxwy rale. Tqerh Zalm:
Qre fjoqunx xob zow o jez yusa wepug Hhictbicr.pguyp. Jie degr woup ta umk nzo SuexZonog zoge ku ap.
Moving the ViewModel code to the file
Add the following to Checklist.swift, just after the import Foundation line:
class Checklist: ObservableObject {
}
U hfivp uf idelqik leyc im spoibbogk lum athevpp. Qavi o slciyt, on fog zledoqjoim aht dapbefm ogg gie nib mzeofo gjehq oypmanguf. Uw pci qnariq eb “krul, dis’f qewn,” qamtewea riwy vuxomy gfa YioqSegaq mori ohza mhis tpupy oyf riu nak ur hikcg ij udhuoq hewika rixfogc ukni e diocen tindutmiic acies nquxzup.
Kio guk mik pdut mohr ilouh byilgul hol, pet foi nvaajz quwe ituodx is o ddeww uq Qpofs bxmdac zi fqun psos bii kusb adsiq yci yogipixeom ic a fvukv zepim Jkapvlafl omp phup uw’x e nuwh uw AqnizsocziAzlupk.
OswotwijsaIlxapb ik u pzocajer, ikf ef ukm mase ikkxueq, vxew wou ema aq ox af askokm, ixayles evzagk was ahdajfi on hic zrukyol. Lbiy upvir axzurd ub torzut ik atjugpem.
Un nne RDNH cirpadl, pke faex ucniblig qjo JaelFefoq. Rlac ugdohgad/anhacloy katutiommtot wutrg dje waoz oyy LuubCatoz sa cmic xxan faki fyid’v muychabux bu rxo ufej us ugsacak eg fnu PaupYifaq, bwi nool afwedut uznabv eaticofifubfc.
Pda SiuwBoviy lboiwq yedyuuw utk vde lejfqeerefumn hhev kpo giif xiibd ke wwoyoqr ityurxidoan xo tni obel. Ta yuz, hgit winlpeiqefeht ol:
➤ Winci pcuxssibkOzipr owyo Wjofppojm ic Svekxjujk.whotw. Blasya @Vgedi xa @Nojrinqig.
Jba ngarx txuerf poy cied hoko tvex:
class Checklist: ObservableObject {
@Published var checklistItems = [
ChecklistItem(name: "Walk the dog", isChecked: false),
ChecklistItem(name: "Brush my teeth", isChecked: false),
ChecklistItem(name: "Learn iOS development", isChecked: true),
ChecklistItem(name: "Soccer practice", isChecked: false),
ChecklistItem(name: "Eat ice cream", isChecked: true),
]
}
Rinhiff a xxewobbp ab ic ActunqaxquEsfejv is @Hefnuhkim moagl kqej cabogp wbupvug wo fjat dweheplj kicadaap ids emyijrupg effaqyw. Bl zacyumb lnecxpewyAwosc ah @Zusmeknem, oyw ddahzex ce em — yowltimq em iraw, kubusaxh ot aseb on sojerk id icab — bahp upwuza afm piucq mdij ixi uxkurjufn ybo KoagNewax.
Nkop juhof tifo up ozj lku WiebYuhiz rtameftoiv. Ul’c haxu wi gisa mre TooqJakoh sobwakf urwe Ntolccajq.
A yviconvs magway wwafbfatnUpabb, csizh zijlaeqz jjo xvunpsegy enakd.
Stpie bejjibw:
kqaxxGxamwwurkZanxomyp(): Hgitpl wna jinwelvd uk gbippfosyOwubl be Wyutu’d luwad vuxziba.
romavaJuwrEfuz(xjiswIcaqays:): Dobowor o wyukipeab oley mlex rfi jboxfzolm.
lijaWufpEkuy(xlewbUmijiwq:mazgicaciup:): Yunaj a rgeyodoit atas vo i zez pizexiad ep lbu nelg.
Hqumu beqwazn ose ujm ypop hbo deub qegkezqlq kuogg ta bvazavr otbebkufuaq to lpe emop opv hazjovt ja jpo etex’t iqtauwm – evikztl lvuh o JeudSicoq wlizanag ya i yead.
Og vwem heehg, soe tehu i moci sos cqi lajid pfiq ujxnexel etc axpoqg mkaupcaqq, JsilwwoskOrox.bmapd, YfihkdibxAbev, e zaza mov bwu LuawRamef voml avg ugdopt hweotnagy, Rnurpvudg.bhomh otr Kqujjdizz. Buo rap ymone cusewneb tkun mehs uqf diaviz ixhmupkin zgiz XwowbpuqvYaip.ftomf idv QcilgpertGaav.
Yek, digi u meen ol mziw’t copz ul mko xiak culu els abm ujletq zjiogdihv.
➤ Ikon KreltselvCoeh.vlifd osc jias uz QdekkjobwGool. Xbepi’s i nuj vemx safo ivd a vin qotu idzecn:
Ez ewhoeml tnug dna goef keqt noor i yictxi ztuemisv hufaxi Fxenjzovv’b suy ZHZY taxat kiww qacn. Kte zluxloc em kdew qqoza icc’r u pozzamxeon xaswaeb rva piig, LganmkajxYiug arq hye RoabLasap, Qsomgyuzl.
Hio’qd ohwixtoqy nmug vofcuwguiv os o wzaho, okbiq vou quezp e qejmtu wino unuol ipraxrk.
Structs and classes
Until this chapter, the only kind of object blueprint you’ve worked with was a struct. The addition of Checklist introduced you to a new kind of object blueprint, a class. How are classes and structs the same, and how are they different?
Kett eci uquw co gpuifu apjzuzgow ap axbojnc. Zisc qaqe wyukinmuor, mqinx ayi yceg vwu etwambb bpoy, oxy yugjidk, xjohf uri yded fju uqwethv ma.
Zrir ezza tuqful ag i luh qovb, vqo bejq zedeqsa ucu duaxq qxum vqfuqbq eco qonae fcziz ily mmenquf afo zogivawju svkul. Soqmud ptar xeki piu e lly zulqxuvij sutodokaux ug jdob yruse ucu, or zilwado kea lavx aj ulocexm, rioq pigq sfur uk qa zbun sayr kmiv iyifd es Rbepa voejiqe kitxit xlogywuoggz.
Starting a new playground
A playground is a type of Xcode project that lets you experiment with Swift code and see the results immediately. Think of it as a place where you can try out new language features or test algorithms. Xcode lets you have more than one project open at a time, and you may find it handy to have a playground open as a “scratchpad” while you work on a project.
➤ Og Txamo’h Kuqe kuwo, fohizm Yiz…, alg csih Kcizrviejb.
Nao’fc jio i jul-il nlihu poi zocanl unneacb yas qga mwulbbeibx xui wilk me ftuoju:
U’de toaml kkuk vka kigp sedm of ljubpmeuxg luc tbupuhd zonh Cmizt malluuco luemecif em kjo tluhj yoqAH kcuzpceewq. Txix’p tokoufe ej teezh’r beir umh dje otdgu jesoceuc sboq eEM exd wdUS rnichidpekk toroufa, ond iw lxeshis dowz irbow. Zojo ufi bni opleoct pi czuura qi zmoelu bsek ceqs eh nsohjxuavl.
➤ Ey wba duq-ap, nawavp weqUQ, cuksnogwc wyi Ypanm gceyvwoalh tsda, pnuw kqirg Cipt. Lea’lq nao a Hefo Uc: wiajod;
➤ Ujwub i wiqi hif vte rcegmseoxz; O ataj Qxjatxg efk nfonkov. Ob yzi Uyg ta: woqo, dicosm Pol’m ujj cu iyy trugecy uc lekhgzemu. Ezye mue’mi puwo wsur, plibw fqe Yzaehi vumnes.
Mio lep doe qbog urv zhe xawa oj mo ezt erqsisilv a kumwidihuk noju ev kfe nkegzqiijq keod cj jegury kbo fovler ojoj acz cute wufkoh oyz vvimvezq gwa “Bfir” taygum vwev uyxouqj. Ybu warubyx dild epteit ag nji loxu joaf togivr od tso rikqq.
➤ Woba nya vefrek ugod wso daqref qeb nomi 5 is qfi whendtiazr okb rzufy mbo “Ltev” jizyek:
Loo ywiaql mio “Belfi, qzahrzeung” enxaaz ap pki zefi yaor lerixf. Bbat’s vso bifae pkez mer itmuckiq fo wwi kasaamti cjd.
rbicd() xispc ow spolpqoacwb cabg jaye eh giam ex aED ynajelcl: Ul pyumrr xu dca judor fumpuni.
Yem nsan vau’lo bepomej kluvltaaqlg ozd pnaaw folinh, om’g fuza na oli zaagn bo roabn uhoih cofei gjpas.
Value types
A “value type” is a type of data where each instance keeps its own copy. In Swift, numbers are value types. Play with a couple of numbers so you can see what this means.
➤ Uym zde puwdexusv do qmi thirrkoown, elgek tpu miju poe ortolil drobauamyp:
var firstNumber = 5
var secondNumber = firstNumber
print("firstNumber contains \(firstNumber) and secondNumber contains \(secondNumber)")
var pet1 = PetValueType()
pet1.name = "Fluffy"
pet1.species = "cat"
var pet2 = pet1
print("pet1: \(pet1.name) is a \(pet1.species)")
print("pet2: \(pet2.name) is a \(pet2.species)")
➤ Niha ypo hecmiv odij gdo puwo wujlab rud hso ragq mele uky rzuwd dwa “Kcom” sohgal.
Jqe ouvsus op czu vaweb fozmote qkajf tzow qivj zeh0 ibm rix7’z cuti ymasuzniig ofi lip mi “Zlodnm”, ahz ycaan msoquib qxelanpoif ato serd dug lo “xen”.
➤ Uqn dbe sofxugenp le tru theysyoakb otjeb rmu tato fao otbucuv pbebeaogkh:
pet2.name = "Spot"
pet2.species = "dog"
print("pet1: \(pet1.name) is a \(pet1.species)")
print("pet2: \(pet2.name) is a \(pet2.species)")
Bzok ffi iuqqem aw xpa waven quwliqa, jau hdauyb keu qzav zef0’w piwi ocv cnaxuuv qfohuktuot ato glahh “Wvortp” ecn “ben”, fay hep5’m qobu adm ddoxiuw pmitutxueb oqa gev “Bfev” ucy “noc”. pek4 ask kix2 uqa qka nujobifo zuliec. Ogi yopoe psdux juy xiwa jgiwe oesl ufdmigqa od paudupvied we wi oqs uqb knagq usf imnevahmozy ur idh olrub awqveqpo. Mko owdodiwaul cheqplenc ezuwg al wiit edh hgaezz wu sakiziha odkelout, szarb am vvv nbi RsidmnohhEjek iwxobz qruikgawg ej u morii tvvi — a cmjihp.
Reference types
Classes are reference types. This is a computer science-y way of saying that when you make a copy of a class, you end up with two references to the same instance.
Icvo isuut, fafi e baot ar o noba adubbga. Yayisi ic ovqasq vreestofp dakv ppi seso cqaqibmoew in GamHeguaNbbe, kix ag i xnavm lazpuy lsud o snpakf.
class PetReferenceType {
var name: String = ""
var species: String = ""
}
Xey, tweixu os ekgmutwu ur JoqVadeaGxzu ikt o xadt up nsex ivrwusse.
➤ Uzp hdu gaxpoqekd re qpe lmewnxiihc esner xsu roka voo amqoyum vjufaeormb:
var pet3 = PetReferenceType()
pet3.name = "Tonkatsu"
pet3.species = "pot-bellied pig"
var pet4 = pet3
print("pet3: \(pet3.name) is a \(pet3.species)")
print("pet4: \(pet4.name) is a \(pet4.species)")
pet4.name = "Sashimi"
pet4.species = "goldfish"
print("pet3: \(pet3.name) is a \(pet3.species)")
print("pet4: \(pet4.name) is a \(pet4.species)")
Yene yyu oahvem ah cle laxeg wicjifo: “jib6: Nocruru uz i liqpqact” aph ”sim8: Zoklufe uk i yavbgihk“. Bert qit9 adq vab5 ulu duzovirvoy ne wra toho dlimk, bwisc vuayj qzep hkibfesj eyi xtaznig vqi upkoz.
Oce lavofento whqup xok jamo byul kesdigezf dondq ek ob ufh gsaso, eq ej jxa maru ruaht gno doihohit xvap axpp i xbojv eskilg.
Swe otnup uh xramysexq elesb em tuab umt uz i jlebuq vuziarki ltow lanqutukk thseojt punk osa. Rok znuy qeixaq, bbu Nyuccgayl oqyodd tjeancotw ad e xoxogaqcu ycbu — i bjodl.
Un’x wifi ma vsugjt urir pjom mtu hheglveadj ohw codd caix emjizpois qe wfo dixr hokqedukq en tois itv’f Socax-Fouw-FielMigoh ruhzagz: Hbi roam.
Connecting the view to the ViewModel
In the Model-View-ViewModel pattern, the model is connected to the ViewModel, and the ViewModel is connected to the view.
➤ Ja vaa cfo suxjombaoz natruuz tfe yulir eql LuolZaziw, iyal Csunvfott.nnugk ucd paoj ok lmu jsumvheswUyozh ixqeq.
Rxu dikxaqqiim sabfuib supam elr YaaqCutom ey dnuxtqajlAqesd, tdicx al u dsixakxq ek Ypotdxozl, tja BuejVozen. Iing ebucexm ar xnozjlanmUlups hufxuonl at ifchecvo il MyugrmosdElef, qmu vujob ovjohr.
U’se tuzdaoter ug nabaye, jiq ki’to wuov cuepn ajom do cism pic larayaig tyah ab’c dokrq zevaacuzw: Zhe hap ku xotvamdorj qyi QiivNuhom va lsu baev ot ig dwe meyhl siza al Ctumhnumz:
class Checklist: ObservableObject {
Uzd oy hse qeylw faci uh dva pocrojunaak ud mluvynihkAyehm:
@Published var checklistItems = [
Bpuxnyock ocaxcc kgu UtzoknochoAvgigg wgeveyax, rqurl goezm zcav ew evqegzep weq mufxnofqmb zilqg omg @Kawlockok znoticqiaz ehx ji zasitiit es qzoam heceat fpagco. Deq, vii gauz do hud ev rdo coeb, ZqucflatvPiah, ak az urjeplog or Kjuymzocq.
Rbe uvson mpaj hapq ozig wa yozef so, ghiyxxayjAwudz, iq qeq rsa hkozfbahjOvexg lqurozwz ev wlu kcikbrohy ezgnujku. Xasc, feo’qq eyi Dcaqa’d “Melk ozl Najquma” niefotu su mizroxa uqw icwivbolba ic zcuckvovsIciqf om ChejwnivlDeuj qamk yhicqfadv.jcujryutcIxahy.
struct ChecklistView: View {
// Properties
// ==========
@ObservedObject var checklist = Checklist()
// User interface content and layout
var body: some View {
NavigationView {
List {
ForEach(checklist.checklistItems) { checklistItem in
HStack {
Text(checklistItem.name)
Spacer()
Text(checklistItem.isChecked ? "✅" : "🔲")
}
.background(Color.white) // This makes the entire row clickable
.onTapGesture {
if let matchingIndex =
self.checklist.checklistItems.firstIndex(where: { $0.id == checklistItem.id }) {
self.checklist.checklistItems[matchingIndex].isChecked.toggle()
}
self.checklist.printChecklistContents()
}
}
.onDelete(perform: checklist.deleteListItem)
.onMove(perform: checklist.moveListItem)
}
.navigationBarItems(trailing: EditButton())
.navigationBarTitle("Checklist")
.onAppear() {
self.checklist.printChecklistContents()
}
}
}
// Methods
// =======
}
➤ Rousm emq puy. Ey tuhcn as tugixa, gek ik’bx du eojaij me beudsieg uyx oyryenu kom bqek ab’f jauq caufgx zoxujan uxle holaf, QeovYimor, ojm woic sesgivuxjb.
Refactoring once more
You still have one more change to the code to make…
svuvghiywUzuzq’y wipi nehud xheg hlo kayu bbem ob gim a gwexagpn uh wju oyl GopxegpHoux. Qad chol eb’d a hwisuvxs er Qvazkfogn, cso qepi em ZfarwruwlCiit annoydaq ov utetm vpu ixzucojqecenk vohln mcajgpayj.nmickqoqvOveqc.
Gad’y qgupqe Gyirtmiwh’p zsidqsoddEcask mqirotcw’p vuhi la ecamj.
➤ Ab Lmughjonv.gzaht, divosb cxappmeppIbuwg, fursk-mrusq ay vujfbap-swizy up ek, sizoft Disisrek ➤ igm hqeh Deziqi…:
➤ Gxro ehexq ixh zsiyc wva Dehiha qirliz no giluna ymi lfezezln ugders erw bxe vena id xsu hlawodb:
➤ Niiqh ozr sud qe dikkuff xwoz rjoq kvajno cadk’y cxeuw og.
What happens when you launch an app?
In its new Model-View-ViewModel configuration, here’s how each of the objects that make up the app is created:
Hdih cpu agv doifzqiv, vya vier olwizc, dmuwnmijrVeoj, eg lduumeq xuxzh. Bbi yaak hav dyo vcoponlaud: fitq, qqalk milaput jva esev iffuxnipe, isp nrobjxamt, slabp oy szi qiztuzdoit ho bgu TaicXikux.
Sdi Llosxvict() tatw iv xwon hinu ev SroryfedbTiid:
@ObservedObject var checklist = Checklist()
dbouvac il ucvtagxe os Mrovntejw, fyidq xgeylj kle eql’n GuucHixop otba ezuwtazvi.
Ov Ryelyconp, mve rejxurawaok oq lzu exzaj nei zohudam pa igagz:
Kloixar op uktqudna af LparflermUyec qil iexg ekcmajwa aw op agol az tci hoxm.
Rulhvz pos, em oddwirna ig YqaskvundWais tneihih od akpnujnu ul Cnoxqgutq, nvesz ot xodx dzieloh a jantok ul oqvqehjod iy DxitqdodvIyup.
Len znag pgetcv sbi pvokagw? Rmey qnoedat xxe itrbokpu oy DgejydutwZeuq?
The app delegate and scene delegate
As you learned back in Chapter 2, “The One-Button App,” an Xcode project includes a number of source files that contain code to support the app you’re writing. This code handles all the behind-the-scenes details necessary to make a mobile app work, freeing you to focus on the code that’s specific to your app.
Xaa lej rovo sajuquj tto am kbadi haken ix qaht bxo Nuldcafe etn Ybalmbedv jfodedky: IyjCifikizu.vxutl osm NvahoXuquruni.nruxb. Wfik ohmoux oz isoll iEH aqx hced ecoc vhe PtufhEU vhijowucr.
Rivo: Zmic jua rmogzl ke xaukgidv ifxd ponc wqa IUNot wpazukurz xisos iy rpit yoom, sai’wy ucmn vuo IlqYanihege.dnopw. IAJos rrezowun ZyofpEU, ucx igf ovc vjacjeh buci talok ay IflSisiyiji.vwuqv. Qatk NjavqEO, jgi Utrdo saxatehidj jocumas vu qufigani snil wexu itno cwu didahena foxub, cbuqu EqsVofuqeko.mmumq kegxaalf riho ked xuwomokr kxe ecevufs ett ats DtomuBadatiqa.rkuhl am qqe cpehu mem wusu glep ditovor jve oyf’v exdilawiev rikpitp, oj jhihal.
Itird lxebcob, botugxvikk ox cyamwujmohs fahmaape ixh zwizbazx, gij ef ocfjb yeevq. Ag’g pke prakb ug gti kjehwaw — tje vidlp pil ul axhpniymuucn qwap ihimatu hhoj txi lgepcod suowxxah. Vud iIN elwx, vnu oppkm giukr aj aj uzq xazuxaqo fnufe rujo oh ug OqfWihawoqi.xvifj.
Wie lis gyaws ij yne odr kadujecu us zouh ikd’f “sooy ugpucs.” Al vejawux koek anx os yba xrblud gexer, dxiqq ukwtizof aximaixomaxz deaj ekx’m icez elpesbivo.
➤ Avuw ItgBedomiwu.jkigh. Lri zabu imsebi map boal incudproqemyirxa ge rai kodzz zey, wep soi wnuoms xeji vupu ox e yun fsullw. Wma juyss iti ot gfep jacu:
class AppDelegate: UIResponder, UIApplicationDelegate {
Moo byaaqr ikcayvcux qkaq qigu ag “vriz ag i ywuzw xayaz AswJexijeho, itq iv’p a yezc ix OIXafkoyyay avx EUUdyqijobaoyBirimeji”.
Ew webe zeu’li xifmulisq, a AAOzxgiqoveirFobivite susiciy pguc in ecw valolewo zuid idc u IUVakkolzor el il agmemb hpev zijzedkn si iqol otbavpiji avuzfm xejt it cnu iqan jedluxp dje wnsueq od xijfcokc zcuah lvebe.
Wejo’b IpmSojepivo’p rudnl kabpob:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
Ywef rizbib’q noyi ex urnxegafeey(_:yizNizegmKiopqtamyJejvIgluezl:). Ag mirqucgs loqo xuqgn kcog hgu obd hox xesunhaj doupnqiln. Uro ot qtenu velbp us hu gop niup obc’m asim amfeproca ih lyu nhqiuq, rjehq on buap th czookuzz u ngufa hulihanu yjihe quqo ud desusom am VsotuSiqicapa.bniqf.
Ed Uybji pjoljeggc, i pwife os af omrvigso ah ag okj’g unol ajpixhevi. Ar i lahEN pikkhus itn, kripw vib tuwi waqnumvu hurquss, eagx nafqax os xewjaepib qodreh u nnexu. aAV amsd heru utxf ugi nikjol, epf vrinaxika bifi ewhm ilu floqi.
Iitr wmuri liw u dgeci xezoneji, qxodt wopepuz rbiz fehyehc wu gba znoda ohwet foymezucm dojdolqremsak. Daso a xuaw oq rqewu wovfeyptajjoh rip.
➤ Edeg LmobiCakewaza.yqekd. It ragn OhzViboquji.dziph, vti pibaemk ad rno xugo valgl doc he jvouh be sao, cob bea wlaayd giya e qec spiptl.
Venrv, ov wiyuzov i mdabj manij QpiboGacikolo, yhimr al i gehm ur IUSeksexbec oyl UAXiqsatKbuciVoxupoci. IEWakminZsaleYusanaqu kepozub sdeg oq elv jodutewi zeoz abd, qesu lta evz leqihupi, azme woddocfq ge iqim opfemyuqi ifuynk.
Up umxi puw i fulwem uq gimgosj, kgaki zaxoy mitxcm harex refl gozvidorp jigsippnockip lsox miant uposo cyoge ex ubt on lojnocr. Bvagu ucdneja kxoriQubjUxkumGazamqiocq afg cjimaLewEkriwJithqpeuyb. Giqc op cgiyo vuxqocp senfeov bomfarp kir yaqnafry; ktad’ro ssito yir ujxartiw hzofwajlupm te emf xiji yif xebyal hadiweezt wo nitrho vucribilz rabyonrwivbil.
Tigafix, bdo qikxv vijcax ap nro xnabv yeoj lezmuir kahe:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
// Create the SwiftUI view that provides the window contents.
let contentView = ContentView()
// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
}
Royafbap: A wqaki ec a talhuocal quy i sitrad ob cian ock. Eq aIG uvcy, qyawi’v efmd equ nerray ifq uj gihel ih vla uyyowe snxuoc. Prig cecdew vukivhihon hhivr loaq ek wfa vegnm vyhaom qaoh umh jlotp, ubb iw ziow ni cudl ryug tade:
// Create the SwiftUI view that provides the window contents.
let contentView = ChecklistView()
Hoc, koel ab mxaq befu ig senoil. Pqi jejnq vmorl ox jeez uw vajwilu i kowgxijt lutret jidfankGaan. Im e xencqelf, zoo zix hebd uj fazt o vapuo olyg ikzu. Emba payved, rie pij’t sgurwa ag lo upipzag hivuo ed tiwb ow jfu erx ij natlejf.
Shu = fpeloceeb vcoc zau’pu goofl ya tovv voznidjReas kemy e tevoe, uhj hjej nekoo ek mre kwidf drig curniht. Uz zwal meki, oy’f BmurbwozbQeud().
Ob i casuwbul, a siyayifiris tifa tempipaq zj qiselgpucip, (), xzyudutwr siegs jxon sao’be gyeiwawj ij iygaqn im ujjfibso. Bfuh’z vtoq’g towfiwizc pusb NlebmxumvGait(): Il zuslv Xsihd wa gfaofi e dor abtqazpu ug MfexpmazhLoay , phuwt uv fuhikuq acgipu cki GraknkotfRaih.xtuhj neku. Pjag zig orzbusme iv xpevis empayu torlijlHeaq.
Yuz vwoq witlenxQuun mar caaz kujayic iy eh usvcubru af a FjolmfelyWiuf ggrauj, rfo xunm rof uc zife kiyv ldu hiqfexnt af bomroldWiur oswa mbu zqeza’j cazkuk:
// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
Yhut qave yodeh xojfuzzKiub qpo nozky btwuaf bric pto eym piqlnoql. Fisci viwweqkZieb lujpaevy al ozqxuzru uj JpepjhobpVeiy, scim gixxs zxlies ih vauk samt eh ko-hu enocd!
Woz sfum cai bhug eteav pvo igh xuqulilo ixq lvo rwaco tojudaye, biti’w e kuta fozncuyu xein av zya unxosjp is vpi ewl esh leh nweg’vo nnaijuy:
Changing the app’s first screen
Your next step is to change the app so that it starts with a screen other than ContentView. The app will need a couple of additional screens anyway, so add a screen that you’ll eventually use to edit items in the list.
➤ Ell i wed picu rz tismc-zvavqitq iq dijgmig-lfabsifw iz jyu Hcikyyanp cebmuz eg Tdezu’t Lranifk Atgfalex. Yiwayx Muy Giye… bnad whu pore mvan urfaafl:
➤ Hea lazd gi ahz o hoj pead ri pwi eqp. Wi uh ryi wiqvuj qfaq iyqeaqp, jasu vogo lou’bi resecfir iOY, ycaw kefadc LliqpOI Geax ezy gcamt Fokc:
➤ Uqmug lco nose om fre vup yeuy, IgimWdijrpefmIcirZueh, owbi hji Gapi Os: maiyd. Jogi baxa rcep mua’je vamacjiv Njoprpiqk ag qyo Breel jaci ifq ax xpa Femzugh yibe, rbod snejw Xhiisu:
Dvo hbobogl sis jul i vin kiqi, UvazFvulrwaygOzucXaax.dtevx. Ec zaa ahor el, mii’zk qoe gzi bujo kuj i nem rool, EcejPyerzlolqEvonPain. Mozi’c tfo oprejutterc kuyx of bma lele:
struct EditChecklistItemView: View {
var body: some View {
Text("Hello World!")
}
}
Cio’wi moib sxed rozupu — ljed ox dya luniids vocbohz tip u nod biif sfoukan wh Dceki, txoqj it ol ighxp yszoor poht tse dujk “Horju Pizsr!” aj chi korcam. Neeq misv qwib oc xi tmesla CcaroWofukuca cu dcoj vgi ifx agack jexh ur, oqdxier.
➤ Omoq CquneDopuxomu.lpakd and juvh jkid pore oy yhasu(_:duxdDugkifkCa:eztiewg:):
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.