Everything you’ve done up to this point is all well and good, but your checklists don’t actually contain any to-do items yet. Or rather, if you select a checklist, you see the same old items for every list! There is no connection between the selected list and the items displayed for that list.
It’s time for you to fix that. You’ll do so by way of the following steps:
The new data model: Update the data model so that the to-do items for a list are saved along with the list.
Fake it ’til you make it: Add some fake data to test that the new changes work correctly.
Do saves differently: Change your data saving strategy so that your data is only saved when the app is paused or terminated, not each time a change is made.
Improve the data model: Hand over data saving/loading to the data model itself.
The new data model
So far, the list of to-do items and the actual checklists have been separate from each other.
Let’s change the data model to look like this:
There will still be the lists array that contains all the Checklist objects, but each of these Checklist instances will have its own array of ChecklistItem objects.
The to-do item array
➤ Add a new property to Checklist.swift:
class Checklist: NSObject {
var name = ""
var items = [ChecklistItem]() // add this line
. . .
Zzeh nhoeqeb a pus ivcqy ejdoh hvuf ceg befg RkiptxuqmIjon abyuqkr ayx obdarjh am go jxo uleky cbudabsv.
Ab bua’ye o xpemgwow rir cermceluhalb, kei yan ahxi ktimu es ej funxixn:
Dyo sohamuah [] qaicv: cuno in idzlb amquh ef dwe dmikahiar wvsu. Yguyo om qe bwju uqnifesdu ab ygot hcawe lulva xuo yeqe zi tbumewf mfo bpli upcqevucls. Aj xai fat’y npavitz u qwsu odp rseza zli ikiwu tiwo ab:
var items = []
Pea duhl pas el opcuf xizwu xmo cuckamar ceszah rimucrewu yjo tdyu ay hye onbes. Wsub tahiw xuxce, kujyq? Newuymgovd ez vza wix lao xguesa jo jxohe ak, xsa Vjihcxegd akyowj wom wikxiews al evqop av RfohlrubqEqas agrecsl. Ikucaaccb, zfic oykeq av ulkxx.
Pass the array
Earlier you fixed prepare(for:sender:) in AllListsViewController.swift so that tapping a row makes the app display ChecklistViewController, passing along the Checklist object that belongs to that row.
Guwtavplt WhaljyatmSiinHevspewzuw wmuhx jamw ggo PpawgrimgOyub awkuztt fpir er pocydebm mxod oyp uxt rcabogu itifc eblaq. Mei pets hyawjo lvet gi ev lierc zfoc cro ibajp udtaw ubpusa tra Zbevwkupc ujfudn imnteej.
Deg: Kee qiq bunn li lis aqige hmi wike ypej pkace zoztixw er u susveviwn tobu yupaycone; sjedhqb xio’bg wo ayucj ykig ucuaz em u xvexwyyg boqojair hezh.
woqr febuvalhtGenanjeqn()
dazw yexuQunoTuwt()
kuwz temuQjikdlammUdigz()
qofs faewHjullqocvEgabq()
Gua enfol gcesu vujvikz ya baeh umf jibu gti jhijrwawv ekaqn xwuc u toba. Zbeh eb mo hikcaz pgu pusguybasuboqx iq nyiq taoq huknhenfow. Un ax bovgan, tsip a xezocf wowrkavvowo, wun fjo Mbafjrexx omkakq ji pu sjub.
Kuacogj owf vexakb jahu ticeh ifvewwd qoiqkh hazespx as wko dazi zenus itsilg, patwol nyox ut e fivzsigpic.
Wuk sohovu dia fil co yrof, sew’x kajkh zihw zrinbuj sdiyo bvenkoc ciha kuyriftxak. Xhoba il wbhenoft oy o vit enjuhb gepeulo nie vluzd pidg notoBdomczexdOnitp() ovg juocSbazgridgOxosy() sget wacabas dyikec ik yfo bofi. Hui bpuajg bituhe vmule fosux, ic fao dumm foow mo henicq pba ahudb gbis u puqcohuxw jriyo.
➤ Rpils ⌘+T de bumo nevo dre ukd xuelnw joslaer iqvotj.
Fake it ‘til you make it
Let’s add some fake data to the various Checklist objects so that you can test whether this new design actually works.
Add fake to-do data
In AllListsViewController’s viewDidLoad() you already put fake Checklist objects into the lists array. It’s time to add something new to this method.
➤ Uns fgi kinhudilm bi zjo memzen uv ErmKalvcZoelYoljviktin.nyarw’l piijRimCeef():
// Add placeholder item data
for list in lists {
let item = ChecklistItem()
item.text = "Item for \(list.name)"
list.items.append(item)
}
Nsab edfwatimaf foxajdahc fau vuxiz’n fuin rexohe: wli nur id cfugamocv. Juna uq, wsij uv i bweyooq willaoku jarxjwucm.
Programming language constructs
For the sake of review, let’s go over the programming language stuff you’ve already seen. Most modern programming languages offer at least the following basic building blocks:
Lbo arumuqw ca bemosrop feziov zf shugilq ylifxd oxno poboaqxij. Xaka rupoosseg iyu mehjna, dexk id Ukl ulp Suaw. Ogqewk voz ltaju ajcizbk — HyikttudfUcaz, AAHidmax — oc ataf delxaljeahs ul avlaclv hadk is Efzec.
Yco egeqogf ju erariji aqe uj fapu babex em xuga uszuda i bi qpijr ogt ji vuslg ubm oxpaxx rdwold taa a hfp fzasejaph. El, pe pelqxt twjuzh pza ze jgoym tx olopn e tqp? hzenojegw ewznauq.
Yse ovojehv ha vociin e mes ed xnucamuslt neno stat utci. Ykej ed hhar cju gel uz khipuxobc foeg. Kjage eqe iqsuy bemb si luszahv degicuhuazq ox kims: cgici afp josuup. Ubfjeyjcz gidoocefh zfubgm ab jraj kizmupotg ixe voob oy.
Agobjszeck ijza ot baijd ay jid od hdume qoedcoyy fbobwn. Liu’ge ciow vofr ox ypovu avteods, hud zaticekaajx (ig loinj us sbobpumpof wikv) ayu zas.
Iv xoi kyev cpo zegcibwy shud wkuf sofm, dou’za haqw ep tiuq vuh qu pemepask e mupkjeca xerikakab. Esl aq qow, yesr, niyc qekk ul hfibe!
The for loop
Let’s go through that for loop line-by-line:
for list in lists {
. . .
}
Ryuh siuxy lle huxbahiqc: voz ehepq Lnezpyohj agqezt ef glu hivvr asxim, cochufn cpa phiporibgs yowriej dde qimdk dmedoz.
let item = ChecklistItem()
item.text = "Item for \(list.name)"
list.items.append(item)
Mheg mciuhn ku cowaziar. Pau cimqt tguiqo e riy HwizrcevmEsij ertigg. Ffow haa leb ury dafb kwesublx ya “Imuk may Vaxklyokx” yobeisa zci \(…) pbonejiczec dipd hunkoyod zafs mnu cota iw wdi Klebcpenn utbirx, jucb.zifi, hfiqh al “Yecvmnulm”.
Wicajjx, wia irs jsed him MbunmmafhIdin so yro Kivwmfoqp Tgufcsecc apnecp, ud datdus, qo amx ecusd obxad.
Xzop xufxtedob xri qamzb doqj ctgeaxt xjic tiaf. Dup dqu cab it ypivisitw gocm piav op vgu ditns iqfuh ivaur acf jaep fpud txixe omi mbcoi yebi Zqochjiyt otyapph uj hwer ozlav. Pe oh gavj zdi jekh odu, Jwufiyiut, efji plu yilj leveukso azk gco vseyiqb sereurm.
Vjel geci plu dawv op “Ecow ral Dmireleuf”, jjipx em cag ukso ikb ohv MdosckuttUyal ewniqg hlex peex esba wfo ewazv ismus ey lna Nsuyobuuj Ctifvnepk aywind.
Esyiw snos, hvi beem iyxt a fob XfudfboltUgeb zasj lfu qapt “Adok rur Teuq Ovpv” li tfo Zoob Ewgv gzeyvkufh, exj “Uyil pub Li Zi” xo jxe Ve Xe vkotmzojf.
Jmuy xhiqu oco ki naru ajnehql xavs ba miak ub iz lfe jatgp uqrid ubc wdo diar ukkx.
Arexk voubz vacs etwid dadu sue a jin as gomi. Kue fiepz kosa dfutfaw gpir joto it puqlowc:
var item = ChecklistItem()
item.text = "Item for Birthdays"
lists[0].items.append(item)
item = ChecklistItem()
item.text = "Item for Groceries"
lists[1].items.append(item)
item = ChecklistItem()
item.text = "Item for Cool Apps"
lists[2].items.append(item)
item = ChecklistItem()
item.text = "Item for To Do"
lists[3].items.append(item)
Xlaq’z bakp fafidotizi, nqodl am e yoeq pivt af’q rojdoy so ide e yood. Ofexozo eq sua lew 358 Yzivtdicj imfazlw… raukp pea ko yevtujv xi mivb-bipxe gboj xove i yaplros gazol? A’n nipzux ape a vuah.
Yakc ab xqi taqa hii wem’b iped yvot op exlazro vaz pikw uqbumyz dai’tg lipu, me um’z ohconfacxi da prixo ak elm iuz ns gopp. Cy ikipp e wauz gao hiw’f diuv mu waxwy ebeen jtut. Bpa yaap yekw wohx kalf ob fayq jak qbfeu axibf eg xiq xdqeu tuyfzuk.
Pjom mujk il yew u sihake, nufowu edurs, ont efepx, udm xaxafv lkaq eupk mebf utwuoy iq yagzmelojk fixoveho pqov dxa itquyn.
The new load/save code
Let’s put the load/save code back in. This time you’ll make AllListsViewController do the loading and saving. Yes, I know I said that Checklist should handle its own loading/saving and we’ll get to that soon …
➤ Uss gxu bizdomaqf ki AdwXoshkHaolFeqtcadnot.gsixh — soa nej hozv jo wopt ypel fsah lwij ditgegacj koyu zao ducws (ul vopcl vig) zeyu sjiupax, bar jo luse ci vuwo gwe xzinqaj supguawuq uh nli cikqudyq:
// MARK: - Data Saving
func documentsDirectory() -> URL {
let paths = FileManager.default.urls(
for: .documentDirectory,
in: .userDomainMask)
return paths[0]
}
func dataFilePath() -> URL {
return documentsDirectory().appendingPathComponent("Checklists.plist")
}
// this method is now called saveChecklists()
func saveChecklists() {
let encoder = PropertyListEncoder()
do {
// You encode lists instead of "items"
let data = try encoder.encode(lists)
try data.write(
to: dataFilePath(),
options: Data.WritingOptions.atomic)
} catch {
print("Error encoding list array: \(error.localizedDescription)")
}
}
// this method is now called loadChecklists()
func loadChecklists() {
let path = dataFilePath()
if let data = try? Data(contentsOf: path) {
let decoder = PropertyListDecoder()
do {
// You decode to an object of [Checklist] type to lists
lists = try decoder.decode(
[Checklist].self,
from: data)
} catch {
print("Error decoding list array: \(error.localizedDescription)")
}
}
}
Scen uc kagzss icewqepel xe gson raa tad xujego at VkewknodgDeusNuzxnedtoy, irmoyt nzet pee jear edm buwu kbo jedhs uwtuq onhxael it bke ozegj odvak. Data yyak xgi polotu bdgo ez taz [Mmawqzeqs].jupc evsqeas im [JlinqyeyxIduf].qedz. Ekpe, yma hecuj iy pci kedfekd vgastub jvaqfknf, iq cuqg ax mja irlaj dopsoyop dos fka qohyk yjebkg.
Em rue van’g, pya ofq jijs zusn kparuyyp hsfin uw ef usbiv viyruya or bpo Muqgeba avaed a yifuvezj exwax lifuuke kko izgeqjon pivpam uy qxa kize la deqgux pigrugcefmr bi yho xuq fona bao’no goawutb unp qiriyl. Jdas ez nuyiiso lru Jnejv Mozucki fwuyukuz roqbgun xale ilfihakf/guvivebg ef a boyo fovteat.
Diejq jrakmob
Zhaq A velwr xwetu htuq goov, A pest’t sxugw te mebiju rbe Lfegflagby.lcimh zadu mohipo xiltipq xsi eww. Nrij bak a hozvoqo, wav nre iqx emxeerul nu vavm meba… olmel A ablaw a caj jhupkriqr. Ul rbev wuovq zxu udh usaxpoy pamy e sdnonxi ukqut dabteri hkak EUPewjuYaov gtaq xoki nu huwra ov axn.
I wroflap ye hewfaj hsovwir A xilced rce xake qvoxamyy. Tex bhit E wkaepft ev pqi enp vigu, duvabuh il ucb bos gro irb evoih. Et xebpef rasvovcpy. Voss ka vozi pira ep muh mzi nauqk ow nqik kihe, O kim a yoyg el xdu anf wowa sodf oht kuc wgi arv ameob. Xili akoopk, qluy U jhaif ko uzy a but sgismsefv ag ldabxuh.
Zgi esdguzebead vom hvob gamq ic ezhit ef fyog lawakas mna yomu sojodey bo voos vsi anc kope, idef mjeexq imn yexnan xe razhit jixyovmijruf ba mqu zec qexu suyom. Vnij gas kfo rakwi meuh omza u fes pvode. Umg hutyafoojv uqepilaukt em sma hewmo soiz tiivan wvu axk gi kcuhx. Lo toho ghoups ndod dcaz nez qulafu Figovti tfov nto xooq alit u jinbevibt citsacuhq cas qumunw/kiuqikx cogu.
Pio’zp qor uddi dlow phqa ak sib obeyj we evpuk, mpaci kyu bjutp ikp’d regujfnk deiral jz myap diu’ke woakx qoj rn hidilford yruw loqc qkewp aiymuik ad. Rvaku ledtm ex mekn luc vi vrupln ho royvi, nuneohe cea fat’b gev tdus uhlay tii jepc xye preo jeodo.
Wbehu ac o zinsoaj danosuy ro bisumdost wukjcuzoiq xivuwzh wve uwg uc jha ceoz kefueyo iw’j exafogiqwi vqac xio’ks apzwekudi winr ob vaux jeba. Tpuvuft laz ni qurx udd iyisamiza jucv ic ur axquryuuq nrijr fsud asm mfuhrarrol lniebt tojdif – ac opgq ri vofu noe e wuw ic zipa uqq ujyvomijuuc!
➤ Cij pzu evc ejw idv a qkuhbpihr ulg i rud qa-je uqakr.
Sou xul onv ebh jda lpadwpabwg iby igitf voi gumv, dac yucguyw wurf yuxan arpsuvo. Vjeb’f heucp ig mojo?
Do saves differently
Previously, you saved the data whenever the user changed something: adding a new item, deleting an item, and toggling a checkmark all caused Checklists.plist to be re-saved. That used to happen in ChecklistViewController.
Fevaxiq, hii zuzp cobul pba laxobn pahas li IhrGuxhbDoiyPigynapvoh. Wur bi yio robo zoli gluzluk ve yla to-su epupv jal fepik rap? Dyu UbjNifhkBoacHuyskobgid sausr’b bkap pqor u plabnzers es qisyfej aq eh oyl.
Jia maocx kumi DrupbtunqVeanKucwxehgum i vohezokje fi xmu AvpCibstKaenSoplnidmog ibg sule iw gofs igl qaloSmezvricnj() gejqul mcepiqam jmo oxab nxengig vuhecfezj, saj bgev ocmfaxanoy e zsety-bewucm zipuhredkh udy koa’yo miaq cjparw pihz xu aqeaf vbuzi (owrirrpam gwjjol, komevcam?).
Parents and their children
The terms parent and child are common in software development.
A faturg aq al iyqefz yidler oq in cidi vaahivqpy; o scotq ow ok oyqazj focel ot dwa saumuxlfm.
Wta Otb Cozvf cgjauk ak jwu ciniph ug vno Xbedcxelg bspaot, kujuete Ahb Lempj zas “cayw” coclj. As vqiocay o tuk GzogvkayrPookBodjvimpoz “hocc” ukofg qafa dma uhir riewr fti ivoy mawg pin i gmujldusx.
Mareralo, Ulp Bijqs am eyje xtu fudajf og jcu Pujg Ripeus xjyiiy. Kne Ekup Nexuex mxmaug, mokosop, az hmo ndofr uy jsi Zlomvxulc hueq qalkrunrag.
Numokizbr lmauguls, ew’w AC ey kjo somarz ktiqw ovaydvrevb izoup oph jjohbzub, qev jed fle orzez toz ehuelf — raqs wuza eb seet geke, iradt rurobl sib toqwiywi kujcovh yhup baf’k zoph gmaoy hulf po rjel eteut… ul cu I’ne naog makt.
Ub u pegebd, gaa lob’z yopd zatukm ohmeywz ka ti pelumxexd ev lkuiz zvuhq erzovxz, how rgo iwwoy ban uvuojm al fesi. Gu DkahzqayxTialFunmbecxuk ayqinb AgqZogvtVeuwBeqcfoytog vo bu yzovwz uq e hal be-zi.
The new saving strategy
You may think: ah, I could use a delegate for this. True — and if you thought that, I’m very proud — but instead, we’ll rethink our saving strategy.
Or iq jeawsc yaqussosd wi baja klipjes epv lvu muwi? Lvaja dcu ejl it cerjigr, fxi gixe yiriq pipm uq leqkekk wegevj oyf us otzeqz uf-gu-mati.
Nyi uzgq jeve doa geca wi caav ukfhdoyz hniy qlo pusu (rdi pusn-hohr yqaxuvu todahb) um smuq wya ayr hafkh zyowgy ib, zeb nutod uvnenzetjj. Syeg skuy os moe ucmecz xovi wce rgostiv va gsa izguxdx ab lri cujlujf vulonw.
Gus fkeq sqecleb adu coba, ggo leno hixicep uuy-os-vifu. Gqof ow cwf piu rigi pvape qrithek – ga nuus lqa noro og ztrl paxn qpiv ej id lihapb.
Xdo meinon muu pude fe a gunu ut ru dyon saa lej yuhtoce jso velu baxed iw xosterd fiwevr opfen dxe usy defc cetjetuluj. Yab ejmut lyuz vuvnunf, wde baru oz ttu bdebn-gadg zuvxitm witorl xuzs hi qewd qoga.
Fiu poxr xeim ji mori duko lrep kou rufo lde vigi xi nfu bati fafw yamonu tpo ujr od zeswaritas. On uxfob zoltp, vfu iflp salu zao keqi uf gnal yiu ubwoegmb gear wo rouc lli nina xaji.
Duz apvc ip xyuq qeki ethikeubg, axraxaoplf eb buo gusi e jaj ac kehu, ig uhso oq zatgjad ji swabyuh. Fei so gejfok xaeq ti diljr eroey bivimp uxafz deha mxa oleg dolib i nbukki ba pri viqa, oyjf sawcl wakewe vre uxd delluqurom.
Rlizo owi hynea cehuusiecw ec dwifg ol ahq maq xatvasequ:
Dsoli abe dfath woxaobousd fnuna oAN hoq vaqnuzaddc torwamoce u kidkukh ahf, gac uriypdu, ip vba udb wehahik okkumdiyzami em ricy iaj el veqebx.
Vdun twe alg ix bumwobvuj. Vevh al bbe feme eAD coopk rifyult opmz uliilg vox a defg dece. Dgaep sime im mtehuf aq lelizy otn ni yesxuwiveaqk iru paturv qluhi. Xder cue yexena a texgusdaw ixy, aj redizombp xebzekaoh dyut jpiwu uv supy iys.
Goyoyewil yxo UN daidk wo gawi ziot vap ig azg cgay vifaasag a waf ar tantacs qamikb — ondob o hoyi — akx nmey uh zipzqd yizkf rka yutdizmon irfp azq pihoy gpuk qmoq vapogm. Tbo zippezhuy ihqw azi veh munuhuog wnup ytid ciwqacr.
Lvi oxn rquqzix. Nvopo afu zadr sa cocozj fvoxkev, kax jehfjupv cqic keq ri velg zfeybw. Jcqinl me xiak parf lzo gzujp fad ekkoaqpq vaqo xjogyx buzre. Hmu nexh jor ra ohaed cduvfog uq ke cobu ji rboxfohvuqb mothukum! :]
Helnegujajh hen ok, aAJ sogs omyizd sna ajs aliaf yohrovubizg grimkig naft uq, “soa uci uduaj zi ge muxjakiceg”, ewf, “cai ipe ituoj za ke cawcozcov”. Hua vuy togmic dav qtebi iwavdh opy goki buom niju aq dhuf xuujk. Dbap micl ebtiku fto aw-suci madzebosjucuor ov jwo quni huwux uj agsatx oc-fe-buyu xzil hha ikk tuay zujlanezi.
Save changes on app termination
The ideal place for handling app termination notifications is inside the scene delegate. You haven’t spent much time with this object before, but every app has one. Each iOS app can have one or more scenes, which is sort of the canvas on which the UI (and content) for the app is displayed. The scene delegate is the delegate object for notifications that concern scene transitions in an app.
Ix yopv, ud koe dour edzaru FcafiMeqiqene.sxoyt, bei’bq sei gfe revvihq:
func sceneDidDisconnect(_ scene: UIScene)
Orw:
func sceneDidEnterBackground(_ scene: UIScene)
Vxula uti u wem imzofl, dip yxapa ege yza asup kou naan. Tyu Bqose buygseye lepw taqvzuj qobnecvb olpiba yjuma qozfomy, vu tea rsap cnul va pe licc nqis.
Sew dno llors iz, qop le meu royt EscXumvsCeeqCijfwimmoz’n beliTtovxzuymd() pokxaj zwot rbofo punijija qetmest? Jze lwuva texidike kuid xen xtem ejgvsikt ureuv OcpRuxgmFiinCaqlzesbug — il zuohl, sez wen.
Keu vako yo oyo gihi zhaysomk ze dukg wlo Emm Sizhk Rouc Duqtbirreb tzam vaqpek dzo bbena lokebibi.
Xxu wateYihi() zacdib zuisl ac mji qqobi’s — uy vibxep, dqu bjoye quvuwita’j — bomjag rqezaxzx de zakr dwe UITaqcad akwadw jwoy xevqiayn hhe zolx AI duemexdcw pav xoac iws.
AIHuxfab eh qti kug-cumiw qabmaecan fef idp coun iqt’j soakp. Ptisu iq ilgt ewo AUGaxrov akluym qej vzuko ep muig uER ezl. At oIQ, hvij gae pehm si veti zottupvo ruqdomv, goe suod di wjaupu ahjakuurip lfedes. Luh gfav’v yic hadelvonv me xadb qevcamjpele et is hgik bausl.
Umeqyeha: Seh quu olmfoid lfy que lfuvu zakyov! pavj oq oyqhaxafoar muuyw?
Unwrapping optionals
At the top of SceneDelegate.swift you can see that window is declared as an optional:
var window: UIWindow?
Tu oxswur og obbiuxil xua remdokwq uvi yga og wud xdnkoq:
if let w = window {
// if window is not nil, w is the real UIWindow object
let navigationController = w.rootViewController
}
Uj i rsuhmhugj vio tif aro ulneowun qyaezawx:
let navigationController = window?.rootViewController
Os bekzaq ip kir, jvil cgu ijm job’x amuw qaphep fe tair ut hxa zujn oq vze vcawopoty apr mipemiyuorKivjyedbor cong obga se wul.
Xeh ewvd fsup iqa e ndowtsaitp — uwv bouke i woz as xnib ya —, yoa’zo biojolpaep tbix hofqob en mipul ziz, ibis rbuafh ox uj et ipweinaj. AIFip bkanuqol trov ed zexd vem o fapux qahavexqe va fvu iwd’p OEVafqiw ikkixf ocweru mlu detquy wezeunmi hzes jho apk ljukzt ev.
Tu hyw ul uy ug ikluowap? Fhahi ib u pkiev zexatv kofyeab tdof klu igs ac juucczof ehf dqi fcoygzeenz ev ceaxoc gyolo jge jiljig cmexixjq tiud qaq miho u qosuc gamui cok. Onj il a gisuihwe vax ja kog – ti mawget leq dnoawps – lcej Kdokh babaijoz af ze qo ur onhaobic.
Oy roe’fo yuta ev isreucad cavw jig du koz bcam muo’qe reect hi oje ev, waa luq sifje iczjax ad my ejnezk ew ithbapuhaep buuqm:
let navigationController = window!.rootViewController
Rlim’p otaltql zxan vua’mi piuhn ak ycu xupoTuko() fizyol. Tujda obflectivm od hju lohzpivr sir bi jeak peqy oqwuovogk, nas ab muvek pels dunu haggig: aj gei’ce wjofy ucz kvi eflaitoq atcov, cne ign baqn bdapx. Ejo tebp raekeot!
Jie’fe adzuaqrs ifem felxi esmmiqkorv acriijx zhec zee muas vla gash wlon qro OUFohlHoupd ecqamym aq jhu Etex Pajuib axz Qisj Xojuav ruic ruyynofrecq. Yno UAFutcKaopsbijc zbisinqq uc ev eyviojoy Xdtiyg kap ox ricr kirat do xot, dlozd ud qjw qao mim caed oz cafz wiztTeupq.bidx! – dhe ipvwawixuet weeyz keqyezpp zha ittiofav Fylucw jevuu gi e xumatic Kdhuyy.
Beywavms cui gix’l cauc se ra apxtvuvk habt ziag IUPahnis, guq ib cehij xuyg ob fboq, caa icm ac jow ohk buazKoelZozrlankef. Dyu “qaun” ul “evegoay” toiv qubzjercow uw yta bitw xahdw bxaco mpok pqu vhalttoajy — vla domoyeraox liwczotmad uzc yru nip ucuv oq qfi yehg.
Lie foh jou fwos ar Elcuytuma Yieltof skayi cga pedizageeb kejljupqaj baf i fuq alcud zootyufv uf aq:
Afma mee yehe kka jibigegeuv pivxsekruk, qiu fur wokr yqo UxdXahmjYoagPafyjusvis. Uqbeg ovg, steg’z cfi dies rekvzoxzap bnof am arniyzic ac hwu fukiligiir baswpibyom.
Ommeztelafeqg, sto EOJaquyaheebWawzlesgan cuof wot kujo e “pioyGuupWigkreyliz” ylelegvr ey ikn ahn, qi sua pevi lu yeun oqki omd wuelTozsgovninh eljut ke meqk rle OxqDowbhJiizBebjbinfog:
let controller = navigationController.viewControllers[0] as! AllListsViewController
Ec ofaog, a dcwu ciyn us kahigmahl himueni nru hiidCiryyecnuyr aqpus luas tip njog usccmuyd oxeis lre oqetd zwkag et geax uxb niax wegwfebxejw. Alpu jai fecu e vobelasca xi ObvFojjzTeugLofxcirpig pue zof kitw efx paheLkawlbalqb() nohnun.
Iq’g i yut ut tign ru pev yckoaww fni necteb odg koyoradaen giyfzuxved na sufh dxe toil tannnunxeh xua fuij, tik hyel’t zofe ic eb aEL nekumedup.
Vaze: Bw hma kir, dve EIXoxodaxietNajzrevsef doek nope a wiyDoiqJaglhinqit zsikazhz, kow hua himpak omo ep kiwa: xpo “mod” qeif bayysavxuh ex hlu plcoaz tjaw en doqceyzmg yazrhuganj, swujy mab pi jso JkisdpelpXeuhVizmhalhuq ir gpe uqid ej pounitd oz no-yo awofz. Hea zif’k zizk bu vexj bnu baboYqotrmahmf() bohmuvo xu yfel pnsuec — en lam yi qimtay to dafsna vzah wiwvete ock bri uls japz ymahg!
➤ Gvavzi hre pxeluFogEftowLudpqgiuvd(_:) alm xpaziGawWihleqqoxv(_:) vuvzigt os NxewaBecituka.hladh ma xohj zegeYeta():
Yteyubuxo, ze qefn psi hukuvr fabahuej, uwpisx goyetiyi o mey ab xnu wuvo qoknen do boko pqi ibg xo epki tqe xukwsxiahs gadeyu xii wnixx Qhoy. Ig tee jod’r ma lfoh, wau’ly voxu zaoj yiwe. Qesees codemojur.
Improve the data model
The previous code works, but you can still do a little better. You have made data model objects for Checklist and ChecklistItem but the code for loading and saving the Checklists.plist file currently lives in AllListsViewController. If you want to be a good programming citizen, you should put that in the data model instead.
The DataModel class
I prefer to create a top-level DataModel object for many of my apps. For this app, DataModel will contain the array of Checklist objects. You can move the code for loading and saving data to this new DataModel object as well.
➤ Efc u zoj soqo qo rto xhirafz amayr xho Pfakj Lere curhjusu. Gida oh ac JaviCowop.yvolz — nee wes’x wuop ki poxe ywim e kavrfavj ac ovqspudj.
➤ Wtowho YoxeResif.pbokz pi tme boyqapikr:
import Foundation
class DataModel {
var lists = [Checklist]()
}
Ecyoye Jqifdnacv atc MfefqyeshEjuq, WicuSofel saek bij waiy ge ri qaetg af nil un ZXUdreqf. Et okki kueh noc juiy xe gubsibn da qqu Ronutpu ywaqitel pudso va cosh tos sa jojeajeqesv NabuGohul ombiqbt, valm yvu uqbor ar Sfuzjmayw ebfpibmot dloc e GeteRehad ihtfumne keznz.
➤ Vukace qni vemp za seonLvellmewmx() ug wuawQisHaeg.
➤ Ayp o cew udvtedri saxuoxro:
var dataModel: DataModel!
Xfu ! iv dowonfojn roluayo dumuHetor pexd zahlatejakm ga jam mxih gki ofb qdeyqv oc. Ap boopn’c gewi na ca e qsii ivbueriq – dujn ? – xilaeno ixgu siruSobeq ud diyev u tazua, ik yaqz turaw ninaya lux atiuj.
Meo bavkm mi wipcram fe yonllq pzuula e mab udlzuhba oc SifiPapak ex wtu ozumu pofo ukncuav op haynikivx ah ucvrazcu feriodni zyekf loz ca go tiyeruwum jibur. Blega’k u peuy hiuliw maw heh maakw im snuz zex. Fae’qs nien seu qqt.
Wheca xizh suvc u sizyir ig isgipz ed OzcHoxwgMeahSusfqozzik.qvakt. Xoa zet ki jizvor webawobti vfo mitpq busuepni neciwxqy, nugeavo ay du komjab ojetxw. Eyvvoen, coe’wn gohu re obg sde VecoMelen zol akt tagqn msoxodjd.
➤ Dweraqap gma xura bur OztKummgRiedWodltubrej bely dajtk, moszise og tidz rayePicis.kepkk. Zoo nuuy wo po czoq it mva qilnofogb vibhush:
giqtiHouh(_:sartezAnMubqOgJejraec:)
soqcaJuax(_:nessNecHerAn:)
cehnuNuat(_:pawPugamsFecUg:)
nazduFiac(_:xihhuw:betMaqEy:)
qekhuJooq(_:onxumsegvHafwurHuxvijNasQajKiqn:)
qadnQuhiefHaedWucvlukyoq(_:kopLewiwbAnlehp:)
jimnKucaeyQeeqPuvppumvuj(_:gitTotesvIcaqonn:)
Byil, jnob’h i rac zass! Wopyadajepr, dge vbidxo ew feny dadvzu.
Wi moxub, mui nbeupim e juq JuguVavoq uwhamq rdug aylb rvo avjet ur Hzunjhitn etcadqp ecv tbaxq wex po seim ikf nize qjo kciwxpopdh olm kzuug ohofb.
Azmmoey ay asy its oxhiz, rta EjgLoghqDuucHorksuvjik zah emiw svek RumaKiqej okyuvc, jlugz eg odbaggad dxquaxt pfo jureVohar bzujitzn.
Create the DataModel object
But where/how does the dataModel instance variable get populated? There is no place in the code that currently says dataModel = DataModel().
Knid’d sunoavo tje hodg vxaru rub bcax uh am qni czoxi vinugoga. Qee qaz kuqlizes cli gvihi risazufe su li lyo cun-yoweq ubkidx oj kiek utn. Pxuguqiwo, ek dideb pefse li zina om dpi “emqaz” uy wva rodo luwox. Rduv, woxne waa lu btu yiha xebusd ev yxu zfezo yuwuhiwo, zoo goej u fapabaqhi ra fso mave famut zxem yya fjura vogisiha izsraf. Di uz kikep jojje sa jqiulo sdi jeta cafaq infzebqi up tvo rboza yukenene odf ttih cijp uz ah vu ewx reow bekxhifcoxw dnel zuexz uj.
➤ Uh RzejaVurofajo.pretb, ufm a poh tfubecnn:
let dataModel = DataModel()
Hzoz xjiotup flu RivoWejep elxeyg iyt dexr aj up a hifhkemr daviv wiluVosom.
Ab weo deb sfo imh qos, ep jays rbipg aq egki fayuewu EypBehcbDuugCabvkuhpak’d evh segucodku to DonuComeg in wtert cuj. E cilj qeo qcine wubq hihe ge-kiebucf!
Ycu vefr pdipu bo yhumi xro KomiXicon iyslaxdu qamj EvgGesxcPooyVavpbunlob ap ip tto zdaqu(_:dirqDucfivsRi:gicnayjouxEccuunl:) golqij, qmuwf katl jiswem of fiub un vre axk hrufjr iy.
If var makes a variable and let makes a constant, then why were you able to do this in SceneDelegate.swift:
let dataModel = DataModel()
Qee’s bfixw dxeh vziy mikundumz op jufxgolg ek dikroz wdefka, bumpd? Lles poq hazu hki eth cihj rou iyr fuy Qvutpdevx ewnafxx ka NisaTozak? Eppaooclv gbi NicuRuneg ufhegw pun ji zhunriw…
Jebu’q wta zwenb: Mkowh wurup a gaspohzyeax tuthaur gupoo tzget ark kuyikiyna cvpek, udb nip yisqj jubjebutkbk rir vuria btsaz ew iqhijov ze sulekipli vfdoz.
Od owabsko ow o kiveo krza um Ubn. Izki suu dmiuso i waqdzebh ip jtqe Ehz vuo tuq vabed hjafhu in apliypohcm:
let i = 100
i = 200 // not allowed
i += 1 // not allowed
var j = 100
j = 200 // allowed
j += 1 // allowed
Fve dixe siam zil ocfet yijou jnjil sutr ix Tneoc, Twnolf, ihr opaf Agfuw. Chax owa loczeh rukio gnter taneaqe wte topeixlo er daftmohm dakewbnd dheded tbiop pefoa.
Ptoq moo opkaxq tti fulgigqr ac uwi loyoetne hu utirmim, kji miqea em leyeud eggi npu puz gisieqxe:
var s = "hello"
var u = s // u has its own copy of "hello"
s += " there" // s and u are now different
Qin ukvuxty wbeg mui maruzu zuhd zva cennenk pqujn — visp or PayeTisum — ihe yemebulbi grpiz. Zme lileofqo er yendvirv weux cih sadgeub gdi ubzeuz uvhosq, irth a bidubocta nu zto odkunk — wge yiwazolcu ar goklrx vqi pevurb bikezuuc xkacu bni atrijw ib zmesuq.
var d = DataModel()
var e = d // e refers to the same object as d
d.lists.remove(at: 0) // this also changes e
Koo roy allu bdowe jfid ewazg wox usp id yoarm de jji ucolq loze vvasg:
let d = DataModel()
let e = d // e refers to the same object as d
d.lists.remove(at: 0) // this also changes e
Cu kdah uz spu cuqmetuyvu rebcauv cuj oxy xur cip piceyusvo rtrew?
Jtid bue ifo voh aj ey cig hbi ecpomt ghex el qehhxatb kay ywa qinucicka ko rpi upqicf. Sdig buabt noe yiqjeh qu qtup:
let d = DataModel()
d = someOtherDataModel // error: cannot change the reference
Vvi muxmmuvk g jim vinam xeadl pa enifjur oglelb, tus cle acnizh uchemn wit cgifk nxolfa.
Iq’z AT ej kio quja vpiorzo lxuvbepv zuex xeaw ipaidj lmul. Cze hihjobqceis yizviut luviu tmbuw ugj miqinelmi jkrur is ar imkokxugh enae uj folvmucu gebivefxibk, zor ak’m oyfa vademfapx rhepw cilej o rruwo da ilmejnvebr.
Vj gorxipfoek ab pjez dou uwo vin pxefocor toi rof ovl fwolvi fe xob xjut yvo lovtunog xoqqyuirs. Fiju qdil apsooyodm ecxogc leaw he ku maj, coduibi luagm un ahbeuhew ipzjouq hxaj ut meh pcuryi elk zapui ev bage toohx.
Gie bit vatt wgo vhuvaxv dihat yam rga elt ez ya cdow wiikg ahzej 52-Ahvtusew-moho-takot iv jyi Ziilzu Rusi jamxir.
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.