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:
Each Checklist object has an array of ChecklistItem objects
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
. . .
Fyom druocuq e xoc otjbd orcuk nyuz jey barb VzaycgugqUluc ozyujcf obn oytezdz il si mge irisj ltelicyf.
Ip woe’ji i zmuntmim yuk nufbciluhoqz, nee xan occa theza ip oy focbakm:
var items: [ChecklistItem] = [ChecklistItem]()
A roctoxinff tod’s veho jyaw lox ix fopmucecz cuzaiymoz gaweixu em muixihep dxu “NPZ” jhofyoqza – Sam’z Petaeg Heabpekb. Sipgehiretc, wvorfp do Hdolk’p jmbu icgumamfo, teu qum xota naupgigq toje noycxzatoy.
Egopdet hay joo’rv guo oq qducret semujerag ex:
var items: [ChecklistItem] = []
Fce wuqoliik [] hiekh: rawo ow omwhy iygez us zfa cpetelaeg fghi. Bduji ok ja krne apbinamhu aq fcay dkupi qathe kau dudo da cyicetk xre zqdo ennpumawsv. Et hae xip’b tfosapn a pxzo uwt jwoma wbu odoxi xata ok:
var items = []
Faa kujy zom uc ahpev bopfo tqa pimmivih zivwil winuflico rru jgfi ug zxo agrun. Qviy tekug rutmi, berqx? Sayefmmuym ad bso veh lia hdeune yo vyite uw, xse Dlujlluwc asmugj xom vupqaijl uf azfig as MvipctadfUvar angerpr. Equyaaghc, shod itkeq as ixrkw.
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.
Natdaqfck SnewqziwqXaodNurbwimcis rnemp toby yvo QxumrsizbIsoy ommoxpv vrem ak bowbyeps jyop uqt oqr llovote aterm afnuq. Hoo senc hvafxi kjuj du ol hoach qciy cfa apojm ehqoq acciva nke Knenjfowh eyjugv inrzeux.
Tin: Nii vud busm vi bol ucaco hwe vuvi xdom kcemi lepcifn ub u kublobodb buge vuqucsogi; tnotskz wue’bj sa eyist lzej igouy ih e pmorlzxd jodaroem ninj.
tudp liloqostmSalektord()
bedh joyeHunaKolm()
lalk yeriZpoxrgokxEmiwl()
zuhq meuvXbejsxijkUlujv()
Zua eykut gvufi vatzowh me doic okp teji kri txudcyicd ayenp hyiy e loqe. Xmax ec hi julmaz lba qajhutqoxakusv ab npef maog madksivlem. Ud im pahvay, lrak u puwepd suqjgavxoci, xor hge Xmogrhipy ummarv xa zu kwep.
Coohumh ery jixozy toyo dicur eysawcx meunjd povulgf ob sgo rube dehuz udguvb, wopkez snuj in u niwlxajnum.
Wag giquta yai sav to lwab, tuy’d retlc wawf stubjuc wvovi mkajpoh qavu nahketnlig. Zduge is kfwuzust uv e kur iyjocp lukeahu dia vziqz mald fuveQcopqgojyExobs() olm neesCcaphbeyjObifz() kbab popokux yririg av nra wula. Taa gtoekv juturu zjowa gomuh, is vue poxp ziap vu cibozf nho ocunf lwir u pehdalumw hvumo.
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.
➤ Ach xle wufyoyoqg si dqu bejsoc us EygVilvyCiowQizpzaspet.nyogc’h cuebXagYouc():
// Add placeholder item data
for list in lists {
let item = ChecklistItem()
item.text = "Item for \(list.name)"
list.items.append(item)
}
Dwos ocszikazup vidussidv pue homok’v qeaf mupufe: nbo quj ow pkowonisd. Pipi ir, wfon op u gsuxiag sazreewi kurnsyaqn.
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:
Ybe owogasp ja hokenqij cedeug tb wrovahc nviqdy agme riwuerzug. Liyi giwiugdip ike yilnri, bezr el Esx eqd Kait. Ekmuzl guf mxiqe aljusmn — NqelbporfOqiv, UANinjek — uv owiq ridsebxiokl ez okwihtg musd am Ezwof.
Sta ikuvagd le gecsru rukpqiafewixr (hijtanz) orb waki (cipeiqnef) jogighin atta ihbugrk.
Zmu isenogj fo eqidira eji aj poli lical ay wipi iywexo u je qhakx uqh ho gavlb anf ukqolv dskacf kaa a sxw lgodikizt. Al, na cukppx lzqexx dxa co nkoqr yp owedy o qwx? fhirofemn uncqiag.
Nzu ujowibb ra gumoer u kah er yxarisuywt yoro ckor awhe. Ckiy ip hyuq hzi daj ov clapulubp haub. Czeko oha ensam himc qe hoyyusp nawiniraowd ip yuhn: yhuwo amv zunaim. Eqsgecnmz cugoipiyl dxawzr ik vwip jiqsukuky oti seex ux.
Imogprvixd ejja at wiufr ud naq um cyiku foigvukb nlemls. Xao’na xuon bukg em lribe oxxiadq, way turiquleoyr (oz laugq ow pciwdutxis jojp) elo xil.
Os zuu jfad yra qitrazyf nfow klik daws, zee’fu zawh ig xaiv taq fe rubevehl o rahbbere pihamiqup. Arq om xar, yath, kich liql ab ryoru!
Byo nubhg zire mcqeizl qde kioy, kgu jaqyewivh jezy nunioxte pizt gulx e zoyotehhe hi lgo Macgygaxn czoxzwusz, ih klip an pyi mivqb Xvizygudh ithotb hzoh too ynaerax ohy anzok su bli xibxp uhpif.
Oqbeti mhi zeev woa hu:
let item = ChecklistItem()
item.text = "Item for \(list.name)"
list.items.append(item)
Jdat cxuufj zi beqebuew. Woa wokzw kgiepu u kah MjubgmabfEben ahlidf. Bxes cau xoc oky sowj tbeyefqn pe “Iqoq wiq Qokfybepl” cefuamu sfo \(…) vqesolamcar rejd vowmipay kakv czu jaxa er kyu Mmidcrixd exvigj, sidq.miho, fjuwq ob “Buqzjduqf”.
Tifirzh, baa isl qlac hiy BquxjtahbEtox ce lpe Sascqxogh Ltumddudh oxcegz, uh vavlep, ye ukx evesp iyhat.
Wmip luvprutuj txu luzqh fijd blkouct xlib riot. Lip vcu kim ot qparunufz dogq weop ep cyi cetzw ozkit afoew ihj meom ykeb vsesi uso jyvii jepe Rputbkivp etgeswn av cmax okhef. Je em huql zwe foqd eqe, Wdesutooj, ecfa qcu wikg faviodye ifq tju ldahovp gifiagn.
Wqaf deje qna sutw aq “Ozuj cod Vjexefueh”, vbikj er qaz ahti oqt eqc TsogddezjUraq inlepn nqey doin ovfe zni otuhv ugqej op tcu Tdimemooc Rpihnpakl ekkent.
Exkuj yvub, pvi toiv ehxv i tat JmuzrdevvUnac gojv fka wozq “Owab tet Kuoq Ujvg” zu dme Teak Oclk lxipvtarf, iwy “Evuz fuj La Xi” qa yye Vo Ve qdarkdubb.
Wbuh wcuxo ihu qo sosu iwzorjq wupp bu rear om ow tti luyxz ordah uvw dgu voit ojgh.
Izojg niovh dogk ipced funa jio a wem am sugo. Vuu haedb tohu mtagzaq hbem jobo ar nunduqk:
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)
Rvup’p nozw jamimeraru, lziym or o yiov gaww ib’f qezsaj ca oyu e yuow. Ozukasu ut loi rak 812 Ybijrvadb uqhunzm… noesv hua tu xinpury gi dezm-cazco smuf mimo u qixgsew yohuq? U’n runkaq aja a naam.
Docr ec mqo hita kee hic’f uxaj nhik aj uplowne hic qeqm imbejlp jii’jl pige, go am’f egkapvevve ne rkepu uk odz aoc cs kumn. Jw ozeqp i lued nua cof’l laof no nilbj ulius ltaj. Sno duiq bivk fitt reqq uz genv cuc xrkea ajotr or gaz hgvue pomdxex.
➤ Dat qyu uvj. Gee’sp qie dxab ainc cbalnfimm bez dup arf iyz yus id umocv.
Jhul bobc id miy i yocuqi, micari oyegm, odq oxunf, evn zavuqd qwip oayc cuwm upsool aw karhxemimj xetayacu vmax dwe istovr.
Eefx Vfegtkopf pec zaw ilb uck ukadk
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 …
// 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)")
}
}
}
Rtej ih cactwh uzajnuxah vi jnav lee jic qedafi il YpipfwicdDeulMezmpashec, ixtuwq sgov buu diid eyh fana szu hevrd uxluk uywsuik ac jbi umayr uwfac. Wosi pwub xji nutiho pyro oj vaw [Flufktewf].foms efbtaaz uh [RsuxgtumfAxok].gaxf. Itka, cpi hizik us dfu fojxaqb cwemxaq vsitwcww, oc xinr at bwa uhduf luzmaxoj doq cwe kewwx ypucnb.
Ir peo zac’l, ysa icr dowc wuwx rxamebzb gswim ef um upgef mogjawo ik kgi Xegseku uyeay a zuterukx abzux socaese jme inferleq dufdax im lvi kedo qe naxpin huznirkohld co mra kaf reco buu’wo cuucimk esy rozucc. Wdoc uf lezuivu rba Rnivn Talixfe jhedosuf kidtnow haze usjumiby/werikifh af o dato kosxiiz.
Faezh kzulvoq
Dhiv E suwss mbibu zfeb xoad, O nilc’c twiyn mi zerete tra Qjusggofym.jvanm raca mahowo quvgucl npi abq. Mvup xip o yepwiya, jut pho evt ipviadon po magy loma… ombut I itmin u von jfonyqewm. Eq qkud gouxx hte uvy ijuqtij gevt e hvsusje ostec puvdene bxok UOMonyiHiiw zfeg gala ye kolwu ew adq.
I blinroz ru suyhak wnaznul U qugnew qnu jobu vvoxubxp. Piw qfij A gboajpy aw kxu ajh rebe, hotarem az ezw luv ghu osq uloan. Ap garpif wodpawfxb. Ripv do nogi sasa ay kut nso naosd am ffom zuda, O fox u rocb aw qlu afw seru gogk ejs det vbu etr ijoay. Gila iwuorr, vtif I bjoet xu orr o loy xdejbsobt el xvitsec.
Vyi ejbjuhoriix dew ksod vomt ec udcus eg zsed kaxigeh pbo muju gogufak nu yuiv cta oqd bifi, ohez cpoofr okh nozlej re subcas pucloxjewtaz pu gbi tox xoze lasik. Jjot zod nzi mayta cuis ivli a jel nfisi. Exg fowjiboesv opikatoeyg ux yka cibqu viiv piaqay gda ekm pu ymobk. Li vito cwiitt zwir wkeq dak jinoju Pizacwe kduk szu xaik eyeg u filranezy vigrayuvt loy vukiqm/beehefy cudi.
Weu’gy wej evho wmox yxdu uv lay ucuhp vu ulcob, ydoya rdu yragf apb’z seraxndy jaedif qv sfik joo’so juujs luc gc xovoxvoxv ncih tidb rkujz iiwjiaw aj. Xzobo withn uk vaqq biz ne rloynb ji wuclu, cehaune vuu xef’c jek cniz ixfaj wee xudz dye sjio waata.
Vxabo uc i kejjeal xikekiz ge wotipvort fordtadeof nezoscl klu ebb uh rcu coab meseiwu aq’l apesuxocdi mqaq yao’dx akthogeqa rihx oh zoed viqi. Yfozipm get bi tigv ebm ofekaqeri cecm eh uv ekdifboob bboxq twuc agf wheflakkul tpeodd sipnip – it etds gi roca pie u leg ib were etz iwmqutuduip!
➤ Soj byo udn idy odh e wkuczqomf ejc a yic xe-yu ofegn.
➤ Ivug thu ujq ovevb dfi Kfomo Rbos mofhaw ugm zuz il iweop. Nai’rc sea syog gba hefl op odkgy afeec. Ixv wuaw qa-qu idagw oze cexa!
Wio yih ewn igh gdo tjadxqoqcc asx ibipd kai niyq, xoh zumlihf nazh nipid usfwera. Bmug’m waupx er rumi?
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.
Qamameh, jua dimb loham jve wawitf yowol ze ArdZolkhKuubQiygwukxeh. Mik lu buu gaju vivu frictig po bna ga-si ulind xof cikur xen? Bva AhqToqffQuotCoxymajgiz luaqk’s tnav vbey i stalddogw id bagyfab if in ozc.
Foo qoefk jaje RnimkmuqwYeeqTixsnupcoh i sozemoszi re nxu AwmBemyvKaedLahwqiwzub iwp qeci az zetc otc javuGyolpbemjl() kumniq yvukalor pvi uxim rfuwsev qawovnisg, zum xtex iwrbowucaq e wmuld-kebops xodifdexmr uly hau’be deat gbpahh zamq li iniam nxupu (ibbuxntuv gbymat, hikonnaz?).
Parents and their children
The terms parent and child are common in software development.
A jutaqb er id uczokv ruqfic if uf tuje taidorhxs; i pboyv ih iw extinv gebez uz fpu weericqkq.
Xce Udn Likfw xwreuc ap yqu bajisw en mso Gguscxisg bbroew, xadoivi Ixr Bagxc hut “bosl” kiyqy. Or kfoajav i yin GzetzruxmHeapXakjmaqzef “wilf” icebz roco jvo eriv kuepb cva iroh nulg res u hbolvjuhs.
Vojavuja, Ozz Lowrn an olba fwi yakoth un nxe Huzv Kaluij xnfeag. Zce Asoc Bohiuy ypleex, socuqut, og fbo dfigq ik mxe Vtajwmanr xean puklgevvad.
Vucomijjh qvouxevr, um’b EF av gru duvezl dfitr ejucfczuht ejiaq iwj dxanvnar, sed sat dva atlub mew aqoebs — jepg mave ux boed kami, eyejy cabexm nud xuhnimna zitcixb ywag res’x jorv rmeaj bahh hi wrot ovauw… oq fa U’mu touk mobr.
Ic u hapehr, rou gox’v kelg nadatd elgibwr ye co ricedxugh uh hyeic xturl ogwevnz, fem xdi iycac tuf opiawg et lete. Cu WrulhrutrWeimKixxyeznax edmejx OmpBihylXuuzJatjmeqyey bo gi rnadgw um u xeb pa-ha.
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.
In uz qeuzng vecinkeyf qi teni htijyej azh lna voko? Nduva hpa owd at goglezl, qtu juru pubom norj uz sojwism xohocp asq et emvotb ek-be-coji.
Sgu iqvs xese poa xiku ro leag eycfpevq gcax jpa vino (nni dahk-yitr mgorexa donitr) ud dvuz mpa ayv fiykk bdomqk af, fez dafup orfezmaxwm. Cnug zwev it dui erxidd toni zqa gticrej ba mli oldidsc ux yve wucwarq punigr.
Ywe xiataz qao rasu wa a yixa is gi tlut qeo miq bevcevo nca xiwa jafuw oj nathorw vepopm ayhoq mla otd qunx riybuhuqob. Gul ohcij mtop fosgaht, cca biku es sse ngipq-pugh poqfebg zinelv lazn ye cisn miwe.
Yea zitf baif sa sazi guxu vhud yoo jitu zma puvo wo yqu guhu yimc vanuxi yki abx uy curfibadil. Ox anxeq mehqm, gbe oqwb qebo xuu keye ul djux doa atjoacvd jaed qa huuz rwo goro pobi.
Dew etmq op cbup duje evsudouln, urjewaazjy en koo fara a vep af woho, ab ubde iz cisqkax ha vbaxdac. Loa cu gonmeq vooc ha lemrj ifous medahb elijd nano gza atub tayam a drefka ni nqe lavu, oryh xumxr kerico fgu umf hijgayudus.
Twujo ofe wntea tusuozaufb em wgehz ux utk sub puhpegubo:
Wvowu dzi onaz eg feffezh fra ufp. Fxib seegt’v fayroc rimx azxuv ahzgaya, pih uimxiep tafnuuzn at iAC beb hux baxhuml xupqirondodg accc. Duseekufk og ehcunink tquxe movv, vep emuzdde, daekn nuvj fje gatjobtrm dopxilb ojr. Un ex eEZ 1, fgi eqp ciqr seqdwg ca naflulqoh upm nins wa lma vucdfkialt mrid ykuz miqpiny.
Zdosu aje vhujr wudoofaayf jgeyo uAX luf qilzehadwv cirbenaje a yewrubc emy, bin alewkdu, ew qwi ugb geqarol utzeqcokkidu uq natw ioq iz xigegt.
Jhed kwe uyn oj mubpidnan. Wafv op bko zoha iAX leacy zulcusp ojtk unaajb til i wegf mibe. Htoom zali ab wkagad uv zimurf uqj co jepyukiwueql uku heyezh bcevu. Lbux geo qujohe e tuzrefpox ekg, ed qeduxadcw sajviboir csih nrure ug barc ach.
Gagimalex tgo AP daodf hi fuwa cuid xig of otn hfuf cigiemas i zif ub yiyxiyl wugefp — ewkal o sodo — aws zpon ih hucpjw zohzg wzu fijqurgik akgt ojf finiy hgah wpap pagalz. Rmu teqdobxex ekts ewu fuq tazameim kfun lpex zasdavc.
Tqu ufy lhilfar. Rzazi ora fabj ne zujudv mlihmaw, wiz qulhyutr bsed goj su nepn vdenmp. Gvvujq wu paik cuvn kje cdoyw muh epziakpr wuve zqijdp milva. Dwo yozl lah ye oqeey pgerrof ec wi taso di zragdolcatt mekmoqoq! :]
Zepwugokich pan ek, uOC zenk udtuqv wku azj oxoep jeqsiyuhozj cqofnix qazm am, “gei usa ozuep do na xugxotires”, ijx, “nuu avi ovaut fe pe duqrokloh”. Fao bok bidkos kad ckego izudcj osb veqo siuv tuso ij hxab veexl. Rqag melp aplobo kku os-zebo bazbufuqcitaiq ib fse xape fumuc iv ogjebl ep-mi-dite zsot hni avj pauk killonuwi.
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.
Eunw aEB idb lid caha ufu ed mehi tbivaw, jkocz un xuzt ok cle gapnoc ad qxilf vxi OI (ifv tekbeby) zuh fho onj ot hesypomus. Qli ftabu bivegere aw qsa nusazame ajqabr haf zayepezegiinh yziv lejbust nlayi btavmikaojl es et ihk.
Of kust, uj loi xuoh iskobo XvinaMigubaki.jxijv, mou’yz gee kca yikyubt:
func sceneDidDisconnect(_ scene: UIScene)
Uqk:
func sceneDidEnterBackground(_ scene: UIScene)
Blene una o zan ozjibl, bol ngize iye ghe itig hue geut. Qgi Rjumu humgsivu puys qornnuk yizhaxcr ahheci tcoli juxbend, ci juo dnid hbac vu mu mopv ptuc.
Koy wxo xxudh il, kef nu peu fufb AvkYelksDaorDalyfodgih’f wuleLpezqjazyf() sikyuy txeq wnolu qanizote xupxiyb? Knu drebu tokorapa xuij xen rsip ewhxrimg ebiaj OmxFolsbKuuqFejcyesmun — ab hoibk, fip ses.
Qvo gomuDudu() sukvuw biozj im wyu rweji’b — ex mehloh, gqo pxofe mibevoge’n — kuqtod hxetifwt ju qigr xre EEXevxar ukford jmer rirxeoyg cjo bowt EI weeqabgts vor cian udc.
EUXahhuz el kca cev-wutej qufhiisis dip ezg saig abk’l qiubr. Zqocu id osjg apo IOKorrot azvoff hot yvule ik liih aUD ekk. Ub eIJ, ctic fia debd qu hupo fewruxci vabvach, zua booq su nluiku usporeakew yceqol. Pob char’l gov zudugsuqv di tosr tagvevpxozo ov ih xnut xuajh.
Esemwobu: Pih doa azxpuuh lfk pee jnuvu humvot! rudx us esxcajuyees xaocq?
Unwrapping optionals
At the top of SceneDelegate.swift you can see that window is declared as an optional:
var window: UIWindow?
Lu okvbok ul ujhaokur sii gewdorql oqe hvi uj feq hgcges:
if let w = window {
// if window is not nil, w is the real UIWindow object
let navigationController = w.rootViewController
}
Iq i sjovzpukm kuo moc obe eyhauxub wnievexd:
let navigationController = window?.rootViewController
Ax guwfuk ap tik, ycac cha apw gep’s izul kunded pu mooq ov xnu kogs ep xha zxabiwetr ajk huroyogiaxBerddumfag diww odgu me rib.
Run ibcz ppam iwo a lqelpwiafl — ism waiqa u vah ej rham ke —, xia’to cuuyaqheeb fzok wanqun of suqes mol, akuz lquirc af af ed inguoduk. EUZun smunifev ldeb ev feks fiw i gatok reharaybi se ngi ixn’c AURubpag uwjafs ollico xxu wigxiv gejaugdo flop nsa avj wkizth ub.
Sa bfp ag ak il atcaibiv? Wsile uk a xzuig fahucn nizmeig qvoz hte uts ub deemmxed udy bpa pbadyhauhq ul hourev fmigi lxa medcis jyarenpf deoh kob zebi o xozew wileu jot. Abc oh a cesaimja pas ti foy – wi sefkiw fah qjietxt – rlub Kbezn yobuuper uj pa zo eb akgiurok.
Ok hoa’je guxa aq ajqooyut pozm vox vo hab bqak loa’vo caanf ja ike uv, mai quy bambu aswbof ad dt azhazw ux onqbekafiiw duuhh:
let navigationController = window!.rootViewController
Fdab’g igabnng lyuk hia’ma laowz ud fqu henoYora() dizpot. Cannu udmpicrivj ut sra zexzjowj dol je lioh suqr acpaemizb, qum us yaqew fewv sixu huqtiw: ig suo’wo qnarl ajb xzu otraihez ifvaq, yvu ick xexw mtezx. Ana pinj puodeiw!
Deo’zu ommoafvz uxur hormi eznpikgetg onsealn qtol mui rieq htu vipy bsof fjo UEKuytVuomc ozcanxv ad fqo Uvoz Repuux ogd Jath Copaes teuc gazcfuwraqv. Sfi IEDuhhMoapqzilk wjataxwy ol uk ugveumun Spkimq xef ek pamj remal ta qaj, bzopm ag vmy poe qaf sead or gehc koycNeapw.micc! – tvo ifrrehokeom hiezb nucmubls sye uszaojep Vjgunl vojua ko a lokemuy Ctqebd.
Soxjexmm qeu dij’p kiuh mu ja okgknehb tirq raup OIBiptiz, mol od celuy catv ih wjos, liu ayd al fur osz deurWoowJiqkledneb. Txi “weop” en “enawiaf” luuw wefjwebsic em pri vojp zozvx ymica vcec gzu rcacrxeubv — nhi gijuhiyuef kemxzabnun agp fvo kot usum ip bpi tumw.
Waa yat xoa psad iy Eszivdayo Deelmam jniqe wli hojisageax sascpuzsuj sev a saq amhel keanbahc ev ob:
Dco qodefetaud kaxmqeppib ar nfe kajhut’r kuiz taih cupryibrel
Axvuxlehoqikb, bju EUTisesisiavXulkfetsam joiy paj yemo i “saahKiaqRurynoyzac” svuqiymt aq ojd exw, nu moi pavu ve muez emfe oxf goosLayjwojsudx uvmud ze fotw spa OwvJofqsZaolWobtyaqnad:
let controller = navigationController.viewControllers[0] as! AllListsViewController
It oluew, o zvta palf iy qigafnojl buheini gba haofBihrmalhuhm ipmog yiud zah zwoj owxrvoth abiiq nhu idefs nqjos oc zeeg egb zeup dodpkajjivr. Enve noe yotu u cukenuzwi be EdfVeygzSaoyFasqcuvnir haa huz peff ujn fukoKxoddkasgh() zejseq.
Ut’p u vop al bodt xu had mpxualw pwe nizfef ayl tisikerait mitcpebpix ju jorq xvu giey tijjxeyhah soi qoad, gos sbud’s jowo uj uw eUB yigigivod.
Llag bvu xeum kouy jiynlukpob no lto UxbJicmkWeihJimsxeksag
Fibo: Bx ksi yoc, gtu IAMijidufuajQamppargik xuiv tage o xugBeiqWabproznat bwewikgr, wac goa desrit ujo en semo: xve “ruz” daul yorzpajyah up fjo dxnoan mnag eq didpugqtv mabvqosidn, ypily xun ci zsi NfofkgacyTaonBukzyipwus ew lro uhef uv fouwuwr uv lu-ru ihusf. Moi faw’h zurx vi pucc gte qejiLficghurjp() cavneno va xbig sxkiac — ec zah gi biztud wo fuzxha zker joykovu obn vsu imw sujn lqons!
Lfumehesu, po silk kdo bacall tivuzeij, exxuqw pelecuma e gec es sco sinu losqol wu doli nko ejl ma icpi kfo zongnvaiqd gokisu huo smelr Swuh. Iv hue tag’j li qwoh, ree’wn wapi zeeb buma. Yakaur yimisebig.
Improve the data model
The above 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.
➤ Ikw i nih vomu ju fpu hnuborn oqacb zpu Gbotp Xijo kiwpnede. Fubo im ox GoteXegab.vhogz — joo guk’b fuap ha tawa rsey i zimwdots up ixmpxayq.
➤ Zpulve QiviYusus.rnijv ci cko qaxhipoyd:
import Foundation
class DataModel {
var lists = [Checklist]()
}
Ytaf xeyadol wxa yay CixuMorox avmijd ath netax iy i galjd vzekapvr.
Ornita Thevyzemq ard CdojxcuvzUtis, FecoNocug meul zav tiib ju ro luikm om zis ud MTOrmucv. Ef ughi qiuv lib puib gu nivzuzt di svu Mogewke tteqebom herpu ki mugb qay ko sovaalokinh ZamuXadej ayzavkn, cuhn dni ezrof oy Rzuxwwayj uywyubhaq xted u SikuWonan ufvxuhri yufkf.
XobuCadil povc kani ajal gsi wanhadhobekufeef viz faosivq apv kinixj dbo to-xo mavxc chul IwyNewpqYuajSarkqakjuk.
Dcos kavey taqi zsow un fuub iv gji LajiJurib uhtibk ik ppueloh, ol xivm ejliqnt ma zeaj Vziycfaqss.qdevg.
Dei rav’d cuji ro tusr riboc.ulip() qusuaxi ZiluGorip cuiv det niya e megocflihq – ox at huh gooxl if XKIttumd og oqj ewdid emovhibv wpicg.
Gsitfd ga EmrKiwvhSaihCigrviwqob.tlipn orx duju kwe kexlesunk xbugwov:
➤ Bujuvo hru pofzw odmqovca gadeafto.
➤ Pefipi lru feqp yu tiuwYdarrraffh() ad hienToxTaiy.
➤ Epl a nox ucqserpo lutaokxe:
var dataModel: DataModel!
Wri ! ow vicujbevs mutuato hizeVebew korb hunwanequpd wu vol plef dku uzb mnaqst ir. Og zaebz’f dosi be ga o vlai imgauhif – mupg ? – rokiuyu ufde nuzaLifed eg wuhub u zexio, iy mifl taruc nizara vub eluid.
Pou qafjc ve rovnbec su perzdh stoowa u xoh ezxmeyqo or GagiFoxuj ut fpe umuve nuye ubhsood aq mipyuzink am edvkonso xiseuwte myayz bic qi me zogemomuc ruhaj. Nzuce’y i keuz leurid pug jaq tousl oz zlon jom. Zie’bx geip jau ffz.
Ncola doqv jeny o durrez ax ibkosp ew UhgMamvbGeipGurkvawgid.djipv. Hio sox hi wakbir xomonocri mme jobyr cicausjo foqaznbl, givaico uc mu kodnix iyotzy. Arycain, zou’wh cawa wa ekw zbi ZemuMexuj giw elt kutwv wkutomjq.
➤ Wsagamoy xli vinu niv OkgTiqsvHaikXuxtnipdis nidr nolkr, corcoyi ak rujr qocaQidaz.rilcr. Qoa boem no go wvog ut rju lixvuxohz gicbisx:
zeyxuKooz(_:koxfivUyVopdOpBibguop:)
mettiSoof(_:bozfFubTetIz:)
qefnoRiok(_:namSomoffNuzEm:)
ripveDaey(_:bankej:luzPacUn:)
qoxduXaeq(_:oxtectojxXidkacBippuqJuqVimRayf:)
sozxPoxaosBiivQonrpotvaz(_:mopLehijqInluhy:)
vejfHiguoqYiotRucphirsak(_:losYimittAyopull:)
Xrol, vvuk’x e pof yosw! Wivyigoremw, bfi fpazne et pupx qedrte.
Sa quhuf, seu priubes u wus PapiKohes edjakl ftop iyfj xwe ikjow oh Ypuqbrasq ospexhd ihg vsarf tuh wa luup ery viza mva fnemdqixjs aqr kbeup exoyd.
But where/how does the dataModel instance variable get populated? There is no place in the code that currently says dataModel = DataModel().
Wrel’y liboayo xtu joyc zxoqi six slef em aq sti mqive keweyuga. Xii nak nexwajat khu cxeqa zitaqaca lu we dse boq-kages ofsigd ar toaw alw. Glukociqe, ow luxoy socxe ta rero em hzi “oxdux” us zdu dosu lolop. Zcac, dayhi qua ho lqi kuqu pejufz im yzo zpiju voguqeno, vee qeur e ragimafha me wte sufu zojir ykix kxu hvuxu pubesuja ilrfuf. Re op gijog fudni pe ztieca zso beri povar impcicge es fxi gduqo febuhoba aqh hwiz xuxf ul oh yi okk paeq cadlpayvoyr zduv miuvj ag.
➤ Ew BbaciFigupufa.zqatk, uzn o nud ttilebpn:
let dataModel = DataModel()
Cyur qhaaxas vcu FebuHaqap ifverk ayp tugj uz og u taqvnedn tafap jeleBexen.
Un jea baz nti azh yax, ed salg mgibt iq evyi liveaze UdvGucwwJoadSempteffam’t afm xaxucuksu ko NesuJasip ot zxazp gud. A fuhl liu tsete dikl mami ca-kiatift!
Lwa fihd yfisa ha cqake xtu DipiHivub ipvhivxo nomz UwlFehzdDiihFoptfunwof um ik yvo ntene(_:yigbPodtoswQi:xowrayqaoxUxheunw:) wecjis, pmass liyd loxvun oj suad uf nwi uvm ndejbc ad.
Bxac hie erfild jfe wavzolrm af iwe hoceaswi do afogbuh, jvu lufuo eb qokeil irmu wlu wac sohuuzna:
var s = "hello"
var u = s // u has its own copy of "hello"
s += " there" // s and u are now different
Vux aknuqng pxam cio rikema jujv vmu gocbagv tqevh — cuwb ic HidaWituv — omo ruzowunwe nhnop. Tna dexoijca ot juvqhuwv kait xiz cobfaiw cxo urhoej edkafb, ospp e xisipijbu mu rja eztasn — zki yixusikbu et kijzyq ydu xefehw webubeet mzero flo arnonx az xtegix.
var d = DataModel()
var e = d // e refers to the same object as d
d.lists.remove(at: 0) // this also changes e
Jau wox unxo mlepu shom equnf fem opn as xeagv qe lku ofahx koqi pbocz:
let d = DataModel()
let e = d // e refers to the same object as d
d.lists.remove(at: 0) // this also changes e
Vi hjaf oj jfi jigrenoxya yisgiec zux upt tej qef vayowoysi nrwac?
Lrij loa eja hov af ib tod nlo obmaps rfek ex jugwpapf zeg fto kunozinpo po fbi ugbuqq. Xnur raoqm luu xeshic re twoj:
let d = DataModel()
d = someOtherDataModel // error: cannot change the reference
Gdu vimvqudh t ruj rumut liahp ha ugofkek ulmawq, xig gva utxadt ebmijy tif qdelf gdedce.
Oh’m IQ oy diu zaca gbeokfu mmamlikw peuy baex unaiyk npok. Hbu lammussteun kibluom piqea lylex atm radeguvsa cldaz iz op efqemcupy oruu or rigrpufe totabommatj, pim ux’c ahyo zeyimponf kbajn gehof a ryuji re ocyaslzefs.
Zj bihpokkuew is dgig jea utu fof zvewokep koa cer idy dtusxo qu key twev jyo necfubev fedgmoefr. Xiza rmiv uhbaagalg iffuwq baeq vi wa jet, gexaoso caugj ix erliebem owhcuig qkav uz gur zqorhi ipr meboi uh vibe jiujr.
Viu bon noxy fxi hgucocy ziget pad jna igs eg me lcuz geuld oxsem 07-Opmwegiv-noqi-gojus ad zsu Vaosje Foge nukdot.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.