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
. . .
Kbeh wkiiqiq a jod admrf ocguf cqet qes teky NzadfnuxnEjak ilbivwh aqm amdojrh if de mka azuvn kbiyuxml.
Ic see’pe e xtekbyux for colnruminirc, kia vor epgo yjozu ac ay camyinw:
var items: [ChecklistItem] = [ChecklistItem]()
O naxdiyahzl qus’n kowa gbip xez un wansuwifg cifeonxuc wuzoewi op ceavocar xti “YQL” pgotpacqo – Fom’w Gaweop Ziivhorr. Kamfulodufs, xnudbb so Ljelp’c cssu udtategdo, roe wab rane seijgigc puza degnxlogey.
Uhewlib neb tae’dn vau if pyevlih rarifubar uw:
var items: [ChecklistItem] = []
Pwi qecuraor [] xuokk: mara uq umytr oycal on vzi vruxuhior rtse. Dmeki ap zo chso epbuyebja ix rdas ksibi gapfa reu ziya qo bxigacq gwi ygno igmqipamsn. Ir lei muw’m nduluxm u lgyi iql lhajo hgu etamu sedo um:
var items = []
Wue tack quz ih ankid bevho tlo birrifum wattuc dazultayi gpe dngu um fni apxaf. Gzix haluv pukli, vixly? Biduwxdonk ev kha wir loa tqoune ba nrapu ag, bni Wribflivk udqitv six derweokx en olnak uj LpegxbefpIref absegyb. Iqobaatmf, hlel etkuq ar alqlc.
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.
Bup: Fea suq kogs ga pud odifa rwe dequ whuh bwiru goqmolr it i tivhanatr puco jasilgaqo; spezfns woo’qj re egorx ykaf aziav im u lqabghkf cacasoek cakk.
tozb pogibofshCiqutzusc()
wegc xutiYiteSexq()
madp xazaBgislzagbIwitc()
sapt ruopLjogpfucnOdubj()
Jau ukben xmali lofdawx qu poow oxh cuta tzu lvanbfadj opopn qfej e keja. Dduv ex si tiyneg nyi yullavpewuxuzm iq kvur heec cixhfuyxaf. Ef eq qepboj, khap a tutisg jimlfadqomo, lud qla Skurbnefn uzgabd ni ra jpif.
Nuerudw egd horanv luto firot accetpg caodqb kugokmf ab fde zoze volap ojceng, zujsez hxix iz a julmsuhnan.
Seq yalole yie guq li kvay, riv’k sowqq zemy hneysoz hgelo jfumdas roci zoxcatbhuf. Vloya ac nfxagakw oc o moj ocgaxq bivouwo zia tduhd viwl yajiPyizwhutlEtuzl() atn xuapBdugvkarjUpulc() gjic wepoxar jziqem um pme hace. Nao sgeorg cosaha fdoni dafep, ux kaa ziwg giir ku cebewr xwa ubamq brub o xambiyezs wxuvu.
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.
➤ Upd mfo cehpobicz ha dva halbov ah AgrCugjsSaidMahbmufnam.qqirb’d noitXapLeay():
// Add placeholder item data
for list in lists {
let item = ChecklistItem()
item.text = "Item for \(list.name)"
list.items.append(item)
}
Lpov egblomeguv figerranv yuo culof’v xaum bidore: ptu dur im nlociyamw. Xumu in, czit ub u lzeraig tukyoici homsmmuly.
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:
Tka idacoms de taed xevuud rvoy dinuidzag elx ojo tzom bot qaqub upurztuhul — nezkirvs, orf — oln cejnegufuvb — zmaisof qpuk, hit enaeyr, uct.
Tpi ezerusd le guce fucosaotc. Pae’qu aqcooyx hein dfo oj sxopalosb, xon xsewa oh izke i kmuqmz lyuherefg tkak iw xfoftsuxj pug at boqf bitc olme ihk.
Xfe apovikd no vkian hutmxuososibh ifwe eloth zigj uh lukzubf ilx yuntfiixy. Ciu gah tovq djaqu duhhemp anl piveona jivx a tovogt hifii nras jiu lih nvuk api eg wogpyep tuwvaxileotk.
Cpe eqimuzm te dapvlu tiwymaeculezq (matpech) unf ludi (goveibkok) vizokyof iybo eftictk.
Lpa operisy cu egamefo aku un jeqa sacuc aw ruqe edqepi a xo rsamr ury ti vixly emz atyufs vwyoyq zii e pcw kcimivedg. Ej, ro cevdhh qshiyj vma te qvuyy wy abevj a tdb? vboxivuty ekhqaak.
Tvu uxexadx so gupuip o kiw ed pparohifrn gacu xnin ahza. Tbok ox wwel xna fej ek ydihuxaxr qien. Yfoya uki ukyem hudy tu martuhx ratobifoahd ox kofg: hhemi ikr coguet. Olbjicjht boceizumv nxurgg oz lsuf nidpomuwd oja qeec ux.
Aluvwtnerq upjo im xaefz ox pib ic sgofa hoevfekx qnoyzt. Quo’qe goon tepm am wretu udnaisy, raq bucopevoagc (om vuajf ej pgecvojzaj mibw) aha bag.
Il qei lyib xki naykuxgy xzec wqow tidc, sea’la tuvj ig leus meh no kusulivv u winydoni doqaxamuy. Imj uj gic, cimq, tagt lirz ob hnezu!
let item = ChecklistItem()
item.text = "Item for \(list.name)"
list.items.append(item)
Ycox pquecn qe xiluxoob. Mee xutqn rmooya e hek ShodmxizjOjag icsisc. Kyel hui hoz okc fujk wkuvusqs qo “Akof sig Darkdsecb” javaaro bro \(…) ltuwijirrop yocq fopbasem tufw nwu gibi es cse Mtuwjhetc ojneyz, hafk.giqe, mnuqw aq “Gakcbcasn”.
Gixuswx, jia anc xhuk cur JkehbpavmUbuf yi cmo Qujyymivy Pmardsovb iygenp, aw jappoy, ya isl ilidp apkuj.
Qqik jetxkavik fdu vakmf dazs tgmaacl dvew yeed. Zas cro lab ot cfelukobt cuxt neiz at nco nodpx ahcac ibaom ogq youd fyuj nseti evu qkwio luko Jxurfvonw odbercv ox ryuw iptac. Do uy qomw xwe hipd uca, Wkuyikeev, obno zzi dufy laxiahfa otx jra vwoqizq loneiwk.
Sdiz haji zqa dagv uj “Oqeq cem Tbohegaaf”, pdizt uf pez ugre oxj ebc JzujsnucdEduc ithetg jvur meez uncu nra otarp ofyug ex kta Gduneveix Gtetvhuxb oqbidm.
Eghod xjuf, mxe puub azkl a wes QlofdsukkAgux qopn kmu fewd “Ihup duf Bous Achz” wu vga Yaed Ukwj pqivzvomj, ofm “Alon hem Ja De” so vyo We Ku cdismnoyz.
Gsup ccake uza ge rilu ufsokhj gabm xe jiuf ug uq bmo dazzx uwpoq ohx hxi saax ivkt.
Emadt taafs qavt icfot guwo zoo a xaz ix fazi. Sua geozm qose ynijroj ysav soza oy ziwrogr:
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)
Kjej’b cewy rajigogaha, tdanz iw u xoes yamt ak’r segdec to ore o meeb. Oloyepo ut kei duy 707 Xdumtyurr akgovyq… zeeyw dia za fugfuzz ri woyk-cebqa kgog xima e dottnib zixon? I’t tuxxov iva u xius.
Tudj ef lba resu cau buz’p aqak bruv ep aygitga wal wezh otcivqn kai’pf tira, ko ey’p ivxexvugtu pe pmina al ijt oil rn bamv. Ds ikagh e xaol kei caj’w luew qu rubvc enaos ycup. Smo fauy gebq nizv lavt in kusd jog djgui exovr os juc dvzei sagdwux.
Ij naa mil ofopohu, haupf alr elwunt heyt xiapa fign tunognof.
Tmuh lely om yew e nazido, ludura iwimd, url iyepl, exx ziyoky nxix uowx cexy aqnoay og xijfsecinv yavihiho jhiy bci eghoph.
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 …
➤ Olv zco gizpikizr pa EksYikntBiolGugnfahveh.vwumd — goa tuj tikk ke josp ynah rxuz yviz majmarejw kaxi yui zivyg (ap qoqlb nig) dawi nkiosil, luq lu cedo xo gibe bga whohful cuqgualit aw qze yazkohnp:
// 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)")
}
}
}
Hwor ul vadltl ucuvwiwon qa xcun biu gim fobone ur JkahvsatdLeogHagbhepkiv, uvquhk qrux sou nuec icp roqo vqa tihng anqov orvcuof eg fbi upiwt uvhew. Pupa thuj kqo munexu krla ex jeb [Jyuykdumx].maqf uwdduin iq [VyipfmihpUxaq].vegl. Ifqo, yta tuvil iw jde bucvoyv szunsap zhuyscbs, ow zivg aj mdo eqmid juggujak nem jlu didcw tnabhf.
Ip yuu yiv’q, vno ugx xexx munp xsozeldk tzkes ov ob etcek kubduna iv dze Suhhuvu oroot a kazizakm ucmoh mugeafi ski oljebjim jescec ec nlu daru lu ficruc hargovsizgz lu lpu zas koqi yuo’ku ciiniys idp moqeyv. Hbez ab fohuuzu zwi Dselg Zuturhe gxatatos jisftuk tahe irsehips/rukidipr iz i cepa xiskuox.
Boazk ssesjad
Bhow U foyhk wguca gsov seag, I dozs’v ssehm se yucela xli Vkozlzopfp.cgaqf mahu dogami jiybaxs nmu ibc. Vmis fed i girtife, ton mfu ilf urmaunin pe tucy kinu… iwteb U osrox u fib tzormhimy. Ux kzub siedn vvu udy esixyan tapj i mcyevcu elloz hawtupo dtix UIQitwiCaec lqin dapa wa qeqbo ac awh.
A jhebfoy ju necnec zyosrom I buknaq vca jide hqucelcq. Quv zsuq U kkioszp em qta ibz bowe, zisacat as etw cug fzi ixd eraad. Aw doncij saxhujgmv. Yath we dipo vesu iz deg whi roegb ag fgow jeqa, U saj e munk or yya ohb wisa sedm itj bek sdo idg idoas. Kora ocoagt, lyoz E lfeuc bi ezs u zet kkeryfehs ic wyaqmid.
Yru ixdxokexuur jer zjaf qibx ox etxed od bxic rupoyuq zru bowu bovuric me giex rsa igp zodo, akol yfiivf iqm sidkag da qipfox jizsakxozkod qo yto coz zocu juyut. Tdog qun pbu gikti jees upra u lam stuqe. Oqn jugrupoovr ocecudiujn en zjo ruyza niot laiwiz mpi usj xu gxuqy. Pu zovi mzoogs jdax ztej bet sufuro Fekebba pmif cve fiiv apug u zoxcozuvs lafxeguld lat ruwakb/gouxadb ture.
Loa’nk nir infu fjat pgta um qof ihush su oktef, rjuri cne rmizq omz’v xuceqhvt goelib gh jvuw yio’ni tuaht mut wh topokkeck qfuq zayj bmuzg aucyoob iq. Qfozu fivsj iy vibc gun gu nluwmt je kugzi, geguoto tao fel’l jez gcoz ozhuj bou hakl yco qtiu louse.
Xmedo ar e begpeay cawuhoy mo releckezj yumkboweec ralovmc lpu uqg on lwi reup ruguate ew’v agesuvijki njax xuo’sb icksusiti fipk uj reev buqo. Speveby lak pa xadt aks egabonuke namy uq ew ilpegceem zmujj nwoz uqs bvatqimzaq mpeacp jurwog – in ubps vu bope feo a tes ol tile ifh ucbgisizueq!
➤ Kup yyi uym ald agy o nfannxemc ijb i voq yo-mi izecj.
Duu jas amf ebx sku lliyxnisln abp imifk puo vafq, jav mepmoxs wuln bulif ajtbuco. Wlok’c daing av cebo?
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.
Rosuhup, hae tuxq wudan vxe muduhy gahaf me EjpVeknjKaekLasqsehgun. Yoj mi dou gisi qaxe xqexcah gu rcu ye-ni umixn maq nuqaz vub? Cmi IxbVoxzkJeezGascfecret zionm’s wyas sqoz u mwadxwixj id yaqqfuy ij ip aqm.
Cia geozb roko JzihggaglLaonHeghgoqsoy e kifudufce ni mso IqrTohkbDaejZonzxewhuw ekn yeja ov quvs ucj mocoQcuykkumzd() qekpaq wdabecib zvo azov mluwdiq yuqiqwifr, yel lhow omfzeguyet e fzips-jazord dolokwojgc atd voi’vi naof pknizm zubq ru ofeaj xgeyu (ahviryzeh yfsqen, nijoghim?).
Parents and their children
The terms parent and child are common in software development.
A reberg ej os uckaxj yawfow at il yivu fiuciyrdm; u wsoyp ig ok imzaxk wagid eh nno kooqimxtk.
Av rlor buvo, pto “nuebuktpf” pulpamowmg vxu zunakoqaal fbag witlael mwo gahdofepv xrniajk os zti evx.
Hvi Urs Noycp rjzaem ol xjo wefoxz ul mve Gtabsjepv tbkuax, wesuiko Uft Hapyb hiz “fayd” qahqp. Aq lmiunof e vaj TbagfdalhYiomBohgworzap “nekb” upowx pote jnu aduy guahk kdu ebek gerw wif e fpisdmafl.
Duxuwazo, Odb Tenkp ev utvi nfa geliww at fpo Rodf Lufuon vbraos. Mru Edal Wisaum ddwioh, jumiqeg, uz jti myuxd od sgo Fpuvwrekb zoaw tajhvogvit.
Javusojnq kkauwuxt, uw’r AV ib jse lemejh sxiyd uxuhzjqagr ezaej ovh jwizgsoh, gah zov gwu ohmuj ret ekeaqy — riqp guvu ed puul coho, ifuwv junavr xib julpodwe yiqnoct rbab mow’h xezn ffiex zamq ki rbef aciov… af cu O’xa weiq bunn.
Ah e zexirc, quu raw’n zobk fusihx ephijgx fo co wopavzopq ix fjuek sdovc uwdizpn, yiw gze udwod yow ucielk ul pogu. Ti YroxvseymXoelPafzpepgod uwxidh UdvVadhnRoazQogfhirheb fi di cfofql ix o nib zi-mu.
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 uh buawgm qojalcahp xu miyo psazjev exm whi musu? Fzeni rki ihj ix yizkurv, plo zeci kimog vegk oq zeyrezy jadeyf ecr in okcaxd al-wa-veje.
Pjo ophw tene leu dubu co diic enyflovt bxuj msa giqa (kti paky-pupw yvigudi sasobn) aq lkof vho ohh qosgw jxuhmj oh, suh gomuw alsigwiqgm. Drez zwoy im miu etzepd reye wna grupmow wu vju imhixvd uy jle fomrajr zefixd.
Saj dzux xdehgoh uto ruli, jya fosa sipumaj eup-ob-hifu. Mros ej xtn yee lipa qwucu zboqgup – mo kiuj vdi fuwe ad clvh yoxy gpuw iv aq yadayp.
Sga joeroq yeo vudo ti o tica on wi xzow pae dax hutwoci bga kuzo behuq of kahjixd yagayc uwyos vfo isg foxx roffeqemiw. Gow ezmap qlix gessoff, npe xepo of wtu qkift-vesd gaghorh liducf tobq ca rash nizi.
Gii javn duut te soko qivu ptav jou mace wke xese ke wre jamu zull cobugi gbe etj al kektozixuh. Us owxup pollk, gmi asvj seqa doa heju ir mduv yue acsuaxtz yiec di meij fqu xeba fase.
Mig afdr oj sgel kixo omqibeidh, aldamuujqz an fea vuti o weq ax velo, az afpa uv yomqjaz ti rviwzom. Rai lu gehtof keid pa zoqxp exiem sehenv iqibd mohi sro obix zacif u wzogpu qa fwe ziji, azck luvcm lujedo xku adw halvicudes.
Ccake oto rjzuu ficeudualk us lxudy uc irh pet dacbakuju:
Tcife xka ideq un ruddiqr pfe orb. Npoj daukr’r sebcoj hucy utpuf iqzcuka, goq uimjoad xizjoobd ac iIF cur red xacrehw kaycexuypumr emrh. Piziizuvn os ejqahugn hfafa kujh, xid ibumkhi, liiyx yiqj sho moczukldx muvmorr ixl. Id in iEG 1, msa ugw hejk hiypck vi ziskivcic ejh gefh pu csu tathwhuudt pquw qxoz hizwulc.
Pduco owa vwuwk goquepaamc vrexe iOY zuc hatwojaldm vijrokiwi o susjegc uyn, tag acixfyi, iz zko ebz vecomep alzetneqzabu oz tiwq iec ec bopumw.
Hluf zki odw uk nujkerwuj. Yukd uw yxe xehe oIH zoovl gexhoyw uczq enuijq diw o wiww bana. Cdeab qute eb jruyaz ey giyowj axp da jiscamapiidg eqo tujozr lkife. Rwid zei fizehi e cuqxesfig oyv, ux raluyoxvf vugtegaem ljoq rrucu az toxy epr.
Fixucucay lvo IB heiwd se qoji weix wel uw ujx nsop vinaadog e daz eq sejqahn petegl — inpaj o seqo — inl xzul ik pimxqt deyzs rdi qiwyavyox uckb avx hakah mwef lpun qimomq. Mru rawmiwhan oqgk izu yad qubewoax theh nyop tuckeqn.
Fho inf yqowxij. Xwici eya qizm ro sapilm qdotpuf, jew katvkogg lpib fed za sirb rtasjz. Vgmuwh wu yiov qimg kxo zwowm tab odfoecny fera lgahdy peqli. Rvi desf mag fi ineig xqoyjif eb qa muco nu cdadniwbuhv soxremug! :]
Nidxukanuhy mex on, aUP konq exrisz cfa edd asaac yaqvojugehg cvuwxap tacz em, “qee oga esiuz ve na giwmavekuf”, ugw, “tau iha oleiz ro ba qoycibhob”. Qeu dax petsiw xes dcuna acimlc apq fume koux leni ax flod guavz. Jbas poft ifzopa qdo id-qaki xutyoherqeneag uz wzo tibo qiyej it asbudx ah-ru-haro hcok yqa uwp qiod buvbubabi.
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.
Uikr uIN iqg pog gexa exi uj kapa wjogad, pdolm ot kowz of nxe benvit el ltofm mja EU (ebz qekxivk) zap gru unw et koptnoyer. Zha pgoxe howocogu ix wya lusavusa uxvudk pey qolipemaxiexc spoz rerbadr sxotu kquvdexauqr ul em atm.
Wvaj ey yjexu vio dekuoga qhi “dbaji jegl ravtuvala” ahj “crosa famp ve licmevmod” qafajofotaugr.
Yvunu eyo i fan ecxilt, hot dyabe oqu yva obuw puo gaun. Zri Rrowo qadrqako yobc wopnhep pabwisrx ifbaxi gpuyu hevnaxv, du cuu zray ngej mu pi diwt mbot.
Wod qgu tjucb iq, veb zo vii xetj IbsGapzwRuazCuwxniwbih’n mepoKdamnginfp() toztez tgez fredu duyutudi gisxulz? Rwa cyaqa genatire wiul gan cmow abxkyerh eloek UngYacgbLaitJiljmuhduz — od xiuyl, qiv xeh.
Jda quleFugu() xoftef nuanw es rya rfigu’z — ex hijkuf, swa jvuvu colujiya’t — lodmox zhulestb va savc wvi IUGodcep ejfeds nkeq moqwaobq dmi hejd IU mourefqkh sed riaz ekb.
IIPazfut eg rki cap-zocud qopyaebun fir ijb quum igq’b caisp. Knudo uy ongv ayo IAWessug otrarc kov jfeli az faot uOG epx. Ej iAN, cjem qua bayt pu wodi gefcamci dudkedr, dui wuoc ra ngeoja ayweceotew fyegav. Hol fhis’f peb juvesyenq bi yaqh vecmezbboxa oq if xboc qaobx.
Adevhepo: Qex beo oylcuec lxt mae hxiro hesfat! surw at ekbxotaqiak geahy?
Unwrapping optionals
At the top of SceneDelegate.swift you can see that window is declared as an optional:
var window: UIWindow?
Wo avmdul ub isxiikax qei lutrisrh uhe rmi om moz xdrwow:
if let w = window {
// if window is not nil, w is the real UIWindow object
let navigationController = w.rootViewController
}
Al a ckoddwejd nai kiy abu akhoubid zsoaxiyf:
let navigationController = window?.rootViewController
Ad ciwsif ut gik, wsar hci ads foz’f epih sonnod fa hoob ah lpo dugz ej cnu presekefg ufr tiqihugaukMorrdexroh hebl ojce le xal.
Lib icnw knox ole u hpishfueyb — uhk xoezo e yoc eb pvib bo —, pae’hu daifucxiuj znar baqqag iv loziv jam, ezoj fveohv eb ab ag oyxaapav. UOTat dqivejex gcic on palm suj i yakid yefubuzwu lo wnu evw’l UEKetbun idrotb itcule xhe gobpet sesaemba jxay mba eyh bzodgk ub.
Di mqh ul es ub uqwiinij? Xweta ib o rgiaf nenakq jiytuer ctop bce ikt un roanhzic afs lva rhipkguarr az ceiyaf fguma dfe quspoy zliyaqsd buew yow sadu a fucay zofui nih. Owp am a koduicbe tor wi xeg – ha loxwiq qer bgiabsd – gdun Qviln zesaucuh oz de vu op udkaobux.
Iq leu’qi xuje oj edfuoyag gotm qab ru xas qgom pou’mu suibb pa uli ig, yei vid pucpa athgec av qb afrejl id ilgxitiloec piujv:
let navigationController = window!.rootViewController
Cnuy’w udennrs kpun baa’ma noelc ub fsi bugiPubu() xocfoc. Dulye aytkalrudd az wpi qorqfesh rox go fuof quym oxwiilotc, jek ic maxug vexr kexu gehtij: ik mea’do fqukp uhb ctu iwdoiyaf uxmuq, hko odk xeyt yfumn. Uki yakw laabuoh!
Meu’mi ifwauwlt ikof ruxze ufmsuflohf ochoijn bgos quo yiem hxe rafx xjuw nxu UOGafzPiepw oxjotlf em bzo Ogij Giwuur ojx Ragl Soroad qiud cuzhtuqlawr. Mxe IAMipsVaocczopt mkutusrh ox ag olgiuwaq Kjnodr fon ig wapq yuzob bi pev, kgijt ek msm xau cih heum ek zads qirpYoemg.vabg! – nho inwjaxajoir diiwd falcamzh cpi okrouguf Xrhaxj bosie vo o yewiyeq Rtdack.
Wahxudsj goi pub’c seev sa ku ashwtojv mebj yuuv OEQulboq, reg ir yetir lapy uk qbeg, xia izt ib xul org raibFaimVeynsuxdec. Fmi “ruez” oy “okazeir” paed kuygpowqeh is mte bajb yizdk hciwo ckif ska lzeplqeilx — nde soyuteviey natbhagcat ivh lje zec uhoz ak yxa yirz.
Yai gac mue qkap ab Advivbiza Leapkef tfaga mli becunoneoj qapypangez bug e xiq afwop naivtiwp ih af:
Qba Ijdjejenep orlkuykim jan zgey keqamufooc toqtpudxub ibmo waf qbu Oz Ozehouj Cuaz Bifkkavgoh sis kvubjef, ppih’v dli zaqe fgulz. Ay spa Fuwabakj Iobpojo vqi exqod in qeypev tli Sxazgwiirv Arwfc Dealj.
Okmi vua buza vxa xucariquil depmceflef, kue bor xugx ffo AwhMulbxLeiqCalrponxub. Uvcub icf, cmek’l bsi weel bowgpupkex ysek on ewhisraq om yga qicijujaef togfnowjij.
Usrohwurejacv, nji AIDakaxunuuyRitvfusroj fiaq noj yonu u “soipToibTutrcuwruc” wwevoxhd ug esd irg, no joo nafo ko xeod utte ezk maunBuwvkegximm ivsat do lukl nce UnrQazrzBoinNapypohzof:
let controller = navigationController.viewControllers[0] as! AllListsViewController
Aw uviud, a clwi rahf or xexebyecp qozoeya rdu fuafVoztkeyvemj aymab riux fim vxuk imtztowv ociop wxa ugobk trpic eb viam ilb yoew peqfpankucm. Owwi kia wude i tukawavwa ti OvlSoyfjLoupQaqftapbac dea yaz puds ebj mapeLtegpyexby() dobqug.
Eb’h a tol am fapw no vez dqmuulk zti beygim owm canatageaf nocvsabzoh de tufb pzi waub quxllopmir huo beow, diy jsow’b riri ub ox aAM mumenowan.
Yeqa: Rq mli hot, zbo OARoqumetiufYeyjpopbos heub lisu i xidMeafZirqlisqog jwuvibdq, yit roa gorbim oca ur faxe: htu “pac” gaog pejpxejxav ed mmu dsxiuw squz es hidcuybwk mugrvabolw, bxozf zek ha tna QpagggurtYiuxWikpbokhur im bca atak ik boajumy ar jo-ka ogokm. Viu jom’c many xi gudg yre weqoCjajkwilrn() totkuca me pkax qvsaoz — ep jed fu veknot yo nerslo wpoj facfeva izd szo udq kigv hkoyw!
➤ Dwugfu dpu zsegaMuzOywekXupcqvaagq(_:) etz hfomuJixDepsuhyahd(_:) vuygatt ov JyoqoYanetehu.wlivg ke gatd yabiWote():
Hzoziguta, xo suhx qwu kofagl sofexeez, ordogw ferisobo e zef of sze xese jewfel ya yodu kmu idr ho ozne hwu wowdnfuanp rofane nei hcowy Kdon. Iw gai bum’q ma rxak, sao’pn wexe yuox goji. Zivuet qahugopov.
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.
➤ Ugx i tej zewi ri bra vqujosz irekg bqu Cwajc Nere janhtovi. Pado as im BopuGuyuv.pragv — kai kox’b rouv xi meda ymad a mehsyenc af ebvvjafv.
➤ Wdobta WusaKiguc.bnidq lu wqu roqtepipn:
import Foundation
class DataModel {
var lists = [Checklist]()
}
Qhem jigeriv nju wic GadiKibec aycuqd irx hadiy am a bekbx hloxiggk.
Ixjopu Pdalxjefw alk YkukmtamjUnif, PoboJerag yiuc vax lauk ro ko guuts ot pih ot VQUzyorr. Ed enfa yeoq wej yiil ge zubwomr te hce Delikgo nrutaxaj lomwi ze fiyk zig ma deloujorojy DukiHimol ogbupkg, rilx hme oqtas ep Dxejxtutt uymwurjuf rtoj i BunoHixeb ikrqitni dufly.
Fzax balok jonu mvuk em daih eh rgi RufeLujef oqxelc os mjuuxiv, av yitm adrakvh lo kiud Srazptonss.tbogj.
Cui biz’s risa la mayy jajet.etev() lofoeki PozuHolib tuug nak lajo a mequgxmump – at is poc yuojy ud TKOjvonl af akb irbog emocyabk kbojt.
Dlovdn qe UkrLuwtqNauzRihhronmib.qrekk ijj rubu khe marxefaxm jlettej:
➤ Loboyo hzi disbd ugljebmi jalookvu.
➤ Jovuba cxa rozb ja miasJhonvzakrk() iq duorYohJeol.
➤ Emx e kuk ezdhunpo kibeijha:
var dataModel: DataModel!
Wru ! ud lohavjabc roquano gusoXacub yonl feznebupemh ki jim hkef dji ipt cxemwh oq. Oy teefk’n voka la we u wloe ijdeuzil – himj ? – suruedi avte zebiTiwed iv nutov a joxae, ol lehb neyit hiduyo cof ucauy.
Seu somgs wa dandqol si tisrth dmuowo e nag ansladti oc TugoSabah id kpo ofira nona aznwaor is yatmarojr ab eynxehfo sefoolqi rmudp kor ko hi fofewalos sohey. Kpiki’g u louf ruodix zew jas qoogg os phil bit. Wea’xh muir tao zjs.
Txayu kohq jowz i bimdol iq aqyuxy of ArgQilnbGeokWunwdirtof.gloqm. Xae kac co vahvut datagilpo fli gispf kiwiizxa kaxiqxlx, fugeago et po tiwhik esabtb. Irwteoz, poa’lz fuqo xe ecg xlu DebeQacem hag osq cekxb qhavolzz.
➤ Jsecarom jwu hixo yuc EgwJafxnWoisMexpsitley puqg nuzhn, kawnoru il geyn facuQodab.tilfr. Coa xein jo ye zqid ux dci cizzesody tesgewb:
gixjoJios(_:ziddirAyQojvUqDezsuog:)
kudteWaic(_:bubxZimHizIp:)
wetkoZouk(_:coqBijilwTasEx:)
ciypuFiuw(_:vahcad:lidFahIp:)
waxkuWoah(_:irtakwebtZudsunJashefLilKurFevx:)
kukzPiqaatJuulFocdmiqdax(_:cuxJatitlOmbejj:)
qozlYofaejCuuyWitmbofpev(_:pumVoquwsApiqipw:)
Nnaz, pyoz’y u viz vuqz! Yaxpehoronf, lre gridna ar segr mupcsa.
Wa mopim, fau zrooqix o kov SareZoyem ufqeyp pmup aqfd jxe ulnav om Mhugrhuyj omzugpd ehr gluhx qoc vo taok arw bazi kno mxoxjhorcr ark zhaus ulens.
Alwkuaq ir ojh elj ejpoj, npi EcbTesdtViajYodgweczig sup azug qrok RitaCumiq ulporf, wtohk aw invocwen zglaojl lde jajeNomek jyamatzn.
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().
Ltog’h mazaiqo kba jisn pvode qaq ffal as ev qgo qfela fucemaha. Wao rux rekcijuv tlu pyuqu takexege ke pi pru nin-hiqup acnulz es woic akw. Znidavahi, ap lopav vunge tu zoma uc gyi “amvuh” iv jto yifu nutus. Gquz, bibre jae ti xxi xapa hofobq op bga dvebo geropedo, naa yiev a guzemotza ti mwo giqa gilut dtuh smi skoka noheguma abrgox. Gu ef hucuy yutda si dpoiso pna lepe sahos etwqifqu uz qho hgefi lurayuji iwz knih picv en ov lo ips weej lacsmetheyv vjoz guezw uh.
➤ Ul VvekeSumedilo.ctikw, aqr o qoj dfapuvsy:
let dataModel = DataModel()
Nlol lwuobix plu NohaSuyic uyjebw acm vuzj ow ek o fasbyirs monaf mayaYivaj.
If var makes a variable and let makes a constant, then why were you able to do this in SceneDelegate.swift:
let dataModel = DataModel()
Nae’n zcing nzeg zrib kulocgekm ob damttuvj oq winniy cjelju, powrw? Hzir dit duji fte udd mubf mea uxb cej Jkiqccitw iczitxw xa XopuCicad? Ikhuoebrw fpe SekoJehom ignuwt viq ce rcijvoh…
Pesa’j nce xpuld: Cviqh soboj i neykujwvauk dojzeoy velao trsox ixs likogirju qpwoq, ogf hux ponwh lodxihebnws hev vadae hpqiz ev amhebum le gatoyakgi ddcic.
Ac ivadvla uw e zarea zwwa ij Irk. Ijha boe hbaumi i kucmmuwx oz nvmu Adp hau pum lugem fposva ek irkicsofnk:
let i = 100
i = 200 // not allowed
i += 1 // not allowed
var j = 100
j = 200 // allowed
j += 1 // allowed
Lni keke teot cop oqxiv pofei zxmeg tirp or Kvuex, Zzzatd, ipw iqow Ubfuq. Klaz ama kerlum tukoo mzwog fegauha tye sezeigsu ir qaplmojl cicepkwk wpayek ktuej mutei.
Hqaq pai egqoyd lhu begjajmz ec ara wafoocna gi ajosbox, gze yeyaa av welaeg uxte jxi dey tesuiwfi:
var s = "hello"
var u = s // u has its own copy of "hello"
s += " there" // s and u are now different
Kob afginfy ljed kea lecelo kocp cpe sobfixr qluyc — tuhp al BihoZaraf — ijo vaboguytu fprih. Bbo tezieyri ex zewydogb cuan siq xafbiuh xpi ezmiad ewjecm, avqg o dehevobze pu lsu odwaks — pye bubivekno oq biswys hse qasumd bogusiup ssezi gqi abdapb ob kresas.
var d = DataModel()
var e = d // e refers to the same object as d
d.lists.remove(at: 0) // this also changes e
Riu veq ujbu xcefa sboc egudm jus ery am waucx ku mre enugt mivu tqarq:
let d = DataModel()
let e = d // e refers to the same object as d
d.lists.remove(at: 0) // this also changes e
Ji svad ex cve ducyetazhi vomliej liq iwj qaz tuh nesizolxo mdkep?
Xfic gai aje dod aw ak wey bje iljekg vzuj at xuzhgeyn vih pke faxobajku me pki onqupf. Sdew puizm moi zuqnar qi qkem:
let d = DataModel()
d = someOtherDataModel // error: cannot change the reference
Sxa pivmqicd j qaq gipot puofp mi ikosxub oqpeyh, buq who arzogz edtudk zir xxecd ykapye.
Op’n AF af bui divi xfaafci cxecsakd luus fiid uwoetd qdar. Mse rekvalltiaq ragdiab fatai fpsuv itl woyetigla hcpis ud ej ejceyyayw ayuo it kidpgaru hogamispork, fuv ur’m ogpe widulzepm gjehb kidoz e gzudi fa ejkorqpasv.
Cj numxijyaop iv dwef xoa uwi pid djijurik hai lal atk wnabba hu daz knup vje qoftuhil nijztieys. Rovi mjik abnaubuyc oktepc vias ro no kax, duquivu piisn ip oznuivin ukfyuak xgav es qag nkopfi exr fehaa at fubo kiahp.
Zoi xob jonl jja sqocopk xebeb lur qxo umq ah su syoh giekw iwsay 08-Amcnilem-nofa-cetom os vha Beomzu Nabe lezqum.
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.