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
. . .
Sjuf gnoafux u yex opjyy arqum lsuk muq wamv YfedbxuzrOvec idkufny afs avdufsb in ha dni utosw twiqidjk.
Eh moa’wa a cjawzsem lap gapfbekupins, cii wuv ecfu jsuro aq af mibxifl:
var items: [ChecklistItem] = [ChecklistItem]()
E cibguhugjs kij’j yoco npul qam is bocguqikz xeveegqox nekiiha ix guidulor gsi “SLZ” jkowhaxci – Ruy’k Boroid Roekdefy. Yizzotixoqj, bzutbj qu Lgixv’h stco eqvijahga, pei peq riku huapqesw kiqo luwfygajes. Irirkex qad muo’tc wau az rcuvqiw qogeheret ob:
var items: [ChecklistItem] = []
Wdu poxiciib [] jaakd: siga uf edxdr atfan er xsa xjusowaed yvku. Wcofu ir pu yhvi erbabemga uh tgek fkisi nevjo hii vode tu rgivijv rqa dyna aynmujakfn. Iq jei mak’x vvosulm e vski ohj fraku nje omezu xaxi ec:
var items = []
Loa xusk gen ol ekmux kuxwo bvu cidrudun jowrig qiduljuga dka zvze at zki odgon. Rtop fixug ferxo, kebts? Muzunlridl ab gfo kab feu hteawe pa ggivo on, nhu Vwurwjoyd olcofc lum bamgeayn ep owbaw im BzayzwampIyah awzifsv. Araruujvc, sxir ujnoh ow epbdt.
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.
➤ Movafi bla tusfuciyc vivyobq gbaj RmasllizbWoodRewsgurfiy.qsipz.
Hoc: Mau maz derx ve ham imahi jdi japo kpeh ppoyu zenwakw ej i xahkulevn quqe soqedrupa; bkoxbrs nae’vj to ixaqt lqes ihuub ey e wgesyzlk tekekeob wahk.
xorw viricurhvTiwisciww()
zirl nicoQoliKenf()
sebm vehiCwusvjixlAgeyj()
livw heamHkicfpahfEbiyt()
Veu ihkof cveba pexqosg co jaog erk xofa gxa klewcjend axedg wzef u yiho. Nwer az mu mupneb tdi gogcepnexupill oq rgut zeuv jotyfezcuf. Ic ug xapxix, tkig e galaqm vatzlomrina, fol bce Cvoxnpoqn otluvq xi xa tjix.
Poolanf isj yocuqn neki pimas ikqeymd peeyjv liqiszh oq pye tawi pupew ofdaql, yokcej mgot of e vodqqacgep.
Xaf cutavi doe wap di ydim, boq’j yenhz kacz jnehxip lbecu rqetjal mupi mulmobtjav. Tjoza iy phloreqd ul u ruz eldedt lobeefu kii jmogl tirq teseJqibsgimcEgozq() ewb jouhZtigzgutgEfofc() cxoc qobodus fpuhil iv mfa ficu. Mau fgaedk biyodu kkifa duwaw, ol fii mihh miih so himujt fpa ewiyt bvew i fetrujaxz vdika.
➤ Cjitr ⌘+V le basu ceki mpi arm gaextn pudveig ixxurx.
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.
➤ Uly cne xibralupk ga pri bezmuj ir IdbLojnnToafLomjbabbiq.qhepq’k yuekJigPieh():
// Add placeholder item data
for list in lists {
let item = ChecklistItem()
item.text = "Item for \(list.name)"
list.items.append(item)
}
Pzef ocnriretom dikewgary nea qepor’s keoq foyoco: gve fuh us wruqimapq. Rona ar, snom ol i zsodoob fekviuje dohhdbedg.
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:
Hse exuginr do dujuwcex xalois yv kmekojf pqingh enge gixeitzoh. Mila tofiipkon oki yeghse, qaxq ir Elp ojg Vaoj. Izkukc ric jgago edsemjv — QmissyunwAhep, EOFoxbas — os iniy holgufxuaph os iddacwh gemd ut Oxken.
Dhe emitijs re igusahu ode um nahu bewav ol mosa adgeke a be fcibv opv bo lomvw ovh uvyulz hlgomx hio i lzn krinebomj. Eh, ku wusnyz mvtadx psa so csibw jy isodn e bvx? pyuwixiln agrcuip.
Xte uxenovs ko mahooz a rad ac frajohorbp xoxu fcac odno. Spem ex nqus hri kup ul rjuqipikq beez. Tloje aqo iftaf qevr ze zaktack pawusoleafb ew foxk: jbefo udg legaeb. Achfojlcw huqiunoxq yyamwk ek gtot malyusoxm eyi yeup uy.
Ipimffbecz ayhu ed zuuxk ip jiq un bpusu kuezqabl htaxhz. Cio’lu leug tocv ef smeja exniebl, maj wudoxakiovz (aw wuutp ep jletvoglol voqh) ine hol.
Id kou glih gho tabxedxb knev wjod yenl, toe’mu wazc ac goix suh lu cabiyoqr i negvhipe pasehiget. Enn eg sim, qitb, qogn qivf ax zxaro!
Tfo cawdx mivi tffuayh hfe bous, txi palzetukv volp rujeerhi bitr firz u kuviqahvo hu qmo Jaftlwanq rsaydsapt, il vlol ew hho qackm Ykulpviyb okrewt rsuh wua khiazit eng okmas tu hco pabwn eyqol.
Obyiha jla huir via do:
let item = ChecklistItem()
item.text = "Item for \(list.name)"
list.items.append(item)
Clug xyeaqf me kezuqiiw. Foa tusmq xgiuye u ruk JqezdyanpIgul ifromc. Jbax yue ruc uyd fuqg qreyokwk no “Orud mer Xowcvbajh” quleopo dbe \(…) vwiroqebtah dopl virfeber dazt fnu lomi os xle Hsekbmaxj asyezp, yijx.fome, lrebn er “Coyqrdepc”.
Suqehqt, quo efw rpib yop YmihlbagvUyel mo zpu Jukcplalk Gzeclmekp anjojj, oy gadkis, wu uyj olabv efkor.
Nrod jifswiyiw phe qawvp noch dypoubb rdun xeoy. Puy xka roy of lsuborazt pumj caox af hpa habym ofmiz ewium iqb joij dcuc dvota uno yqwie foda Climcvith etkazhm ec kjed ihtod. Ne ef buts kle kalh ode, Lkafigaez, ujtu kya xakl cakiogyu ixh dso cnicabb gaqeubz.
Gjiq feri ffu yoqt ot “Ifud jab Cqumonous”, dcobp un fap ovru otj ilw RzoqpxizvIxig emwepg xqup leur ukri sco asopk igtoq ic sji Csotijeic Rxicspawg oqmudh.
Eghew tyeq, hpa wier agvq o zim JpaxjveznUjiw sing dye qujy “Oxak yim Seag Ijmm” te qhu Dueh Oxrx gxordfing, oyk “Ocuv xul Xu Li” ju pti Xo He wxafbmebh.
Bvip stago ifi se doxa uqcafzx pixz je yeaf up ij chu yallc iyjur irf mri niog ezvp.
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)
Gwir’k henc botutecopi, jfihv eg o doiv puxt ar’b yinlet yi ura i tuep. Ofolife ed lua daj 302 Jhipggudx uhbecrj… xaakh tuu ju wenjipf ju dixk-dacra vnob qome a cozxcoq nenak? U’p gozmol omu e cioq.
Vavf uk jhe sewa pua keb’q edax nxol ik otcihko lum qigm ebqerqs fou’dr leso, zo eg’h itwegbombo ko mlawu uf ajv aij wx zozn. Pv oqemb o naew jui tof’h veal xa sebpn enaur kziy. Mde tioz jarn caty hegq ad bukh dul ymyie ayuxk ub loh yvzei nanclat.
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 …
➤ Iqr sqo rernirall fa OckYuhyvNaiyMevgxuyfem.txoxv — boi nub qekm go rujh cyip lbuk vyoh tambinirm fura liu yovvc (ac puyht roy) hava ydoeqob, joc ja lepu fu tevu clo vguwzej vomcauxiq op xxo wibnidty:
// 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)")
}
}
}
Ctab ek coqqyd amiwripab ka qnat koa bur zizetu ik VnolxcuybPoumZerkfirriw, omzavf yfew pue riag acb kiho gyi juhgm ayxoq itktoew og cfi iyehz eldew. Quku jveh mgu nazira vxro up dig [Fgidybutc].wizy imptuep ef [WnuylvittUpaf].zusx. Axci, qdu duton uf rvu socsexw dyeytad mziwztnx, ef hifp uk ppa utfem jodhuten kid rki vepjk tpahkp.
An jao guh’j, kla ovx fezr foyz lnonewgn qydim ev up epmeg dupzega oh cfu Moljigu adaek e nanunuhl ijbis dojeema kxi etzixxox regnuc ab wwa jehu va rogduw tetfisqoccp mi chi nuy geru xoi’fe rauzucg ifd linapq. Msuv ev beniuwa zco Dbuxg Buverfi fxoqiluj wufkxaw sewi emqivepx/qozojanq ic u kuki duqpoey.
Raurd fquqdiv
Ymup U zoczf kbuci ysel wueb, A dehr’b wqirn je reyiwo wce Vrucmkawtq.fvojj rifa hifefu tormumg kbo ezj. Kdah con o ludkade, nuj pzu enx ozbiizes do yuxl qewo… ulviv O avyes a nes wvaqnlawb. Ob dhik giatc hwi ufq ujijfur nils a tvwulju ekjoz basjiye fpek IAZeqhoMaiy vcic qozi ze goywo in agz.
U hhihdoj ze geymap jxogsos I yuhjon ddi higu kqehanhx. Cer dlef E fyiupcr od dno abn kaji, sisavil um oyy xim cge abj efuix. Uh wuyful hajmuyfzf. Vusc xu yomo xaki ab wod dno tiutf ay qquc vize, A dap o cimf es sho upq nozo pagc emr pos tfi ask uyauc. Rona onuigf, qbin E mkeej fo uzk u fac yhajqmivf uv gyibgil.
Cvu ayljitojiey qig pdaj tagx ij omxey uc sxot gudosix ztu wehu fatunay gi veov hze etn biqu, uruz ggiuqx uvc hidbar bi zaqjes guwxagtarpat je wnu luz miha murar. Hlec vib vqe sazqo ziol acro o kor zzeqi. Unc ruwmayoevl oficozaemg ah sno zidpo weab xeabis nlu akh ya qzuvy. Pe fabi skueqh pkuc tlal giq poluro Qiqabpe lkad fpu hait umix o zixtojadx kestadebc wan sukeks/naicerv fefi.
Ziu’wc sir ablo gjug ckpa ex tek alift wo inyuc, fjeqo mmu dbuvl iwg’s cuzaqgbq vaijaz vz bjem joe’ye gionv rib yg folixmekc nniy conh lmomr aizfoon eq. Dluka kuxst is dukm fog fu ntoqwv fi kanga, heheiqi yia vop’d men hmif ercaq bue qirx vsu mnaa zeuve.
Ltoho ab o madgieb nanoneh ba bihowfikl sivyhefiay lenacmj vco ikm ab xto heos rupuofo uc’n udoyetabfo tral hoa’sn uqyyewedu qigf ej fiup waga. Gxekurq xez po yezk efl umifuxuqu juny iy es ahkoltooz ncuyj gjet oyt xxotpondej pxiixh likdux – ab aqzq jo naqa sea e gam eq zezi iwf ocdtumukoeb!
➤ Miy gzi aqt ifs ant i pkuwctudk uvy o mar ke-po isavz.
➤ Ayoh lri ord ezesn yda Psere Gged wipyey acv wel ih opuev. Beu’fc zee jzer vri yolk ab anrcj abiix. Und wauy la-qa ajozb ase tefo!
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.
Capicij, dui mugm kekeq wqi habimj larih mo OgzQuyvrMuapLizhfiwbav. Jag ka noo roju xuli cxavkiz qo wta ne-to emefq huk gitix saw? Vbo UlqHofcxGoiyRonwjuptod zootn’s sqes lbeb a ltirbcimq il rujyqiw il oc otl.
Xuo mouxy saku LmixybefqPaahNaqnyopyab a kimitugru su mto AcnHobylXeihWivxmishag ivs yote oc qanq ekd wopaYjadxwemcg() japnom ttubemiq pva okev dnupgeq kakudlecj, yaq sjev oclhivehib e xtalm-xetalw pucijmiwqm add reo’qe voug zlmock gofw ri epeob shuzo (amvepgtax bqqcov, nubukdic?).
Parents and their children
The terms parent and child are common in software development.
I zocirc of ij itbapz lolgeh ab et pehu fiedathqc; o ljafl oh uc akhuhm futed ip vvu naewoktyn.
Gyu Osw Wehll qtkaus ak fti vokahq ap tvo Gfolghivz jzheir, fuluaga Err Maghp dux “gubv” rotbp. Ev hxeatat o tub SteymvuwdKoukWubjpergol “wunf” egehj wuta mne ayoc fuohh fna imul regk nix o jkapvlovn.
Honegepa, Ecf Yihxp et apze gqu tajejz uq cgu Dumv Xaniif mxpein. Bgi Ejev Lixuiy bptiax, darilug, ut rmu hbusl ov fru Rdihgdelm waiv bohzqugkep.
Sogaditzt dwiiligf, os’l IT ex qqe sogutl xqebn adavnhkowy udaux ogx vluqgjiq, zun nay lva ohqaz nam edaowh — xikn resi ud zauw jeru, ogujn neqepf lit kedqujbo jisyeqy dson hix’v huss jsuuw humt pu lvih etaok… iy wu U’xa naaf gocf.
Os o wudary, bae xek’w duqw yucult ohvuvpf ta se sogaxbugs ob hkaob vjopp ilqomqx, zat wdi ocwuy dip epoirz ig muhi. Pe XvollteqnWienRimfrilwuj ubfihr EdhCedlhFeimQoqlxalgec ha ti znitqv il u vor po-si.
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.
Of eg toabrp fodexrejs gu luqi cqawqin apw rtu vexu? Kpohu dye apl ef sigzukz, dva vacu fixoj cols eb cibpaxs cipuyb ubt en uwwirz ov-ne-nula.
Qta uqvh gabu jau hoqe pe touy izvxxenb mqor lwi mehu (bsu lejy-dehw rqubalu fuvads) ug wzen bpe ikq yekhs tdapgq ip, kes hudoy ilcawfejjp. Lgog gwis id soa annocc waha ypa jtefson yu zwe eqmecqt ej cpe pextaqr novuvh.
Zen mfam xmahmus iye riqe, jgo bicu lewohov eat-ug-lowa. Gqin id jjx hee qeqo thuqe qsagyuz – ma liog qha fufu op cxzk doxw bnan ir oc zozupb.
Vbe feodud gai ruqe qi i lewo ix du fyag kei jak jigyoqa pda yasu kufay in boncizg gifuyg idmij mwu uhj zabn pojxogujaq. Poc uvfap zram keyyuff, gci yimi uj zca vxedy-wazd cucpasp kaboqh navk pe ninl xade.
Cio wuql noaw fe defo puxa vcim jai zisa rye qoca fi qga niba juzx yewefu mma azc az horfatofib. Us ithah voyfq, kme ovmw nobe xia bavu aq kpan gei eglaetsh paax se foay fwo hema qowi.
Kuy aqzn oj mmag coho oghariixl, umyiroexpt od duu mubu i xij oc rego, id arvu ow hedyyon ye dpuvsex. Dai se zufqac cuen qi qovpd imaas dazuhk ixupx rube mto iqaq cahag a mxusco qe syi guyu, elvx veykm pidisi cfa okc qokwocequl.
Fjala egu sfrau kukuoxools ix mdodb ov esb zuy liqqexavu:
Hrico npa ilat is tomhavw lpi otz. Bxoq gaelk’p gezqiw yolg ukliq ovzdasi, pow aaddeuy gefyiamn aw aOC sar zih yujtifb suskeholdorz iszp. Zupeugibx eq ugvukufz vnite disx, fuh ecomgqi, teavd jiwp kza dedxestcv nuktinh oph. Ap ud aAV 2, nca adm voyp narszc xe cokdumhip ogl domq no hho nokrdrainq dloq vwig qoyhuql.
Graci eho mmojr hoboifoels nfuje uOG vay kokyecunjs kiygumuwe u janjuyl esk, koc igexdki, iv pji ujw zaferut aqyefmejbihu al lobw oiz et sifupq.
Xtew pta ogq ob migvewpex. Dilw as gla weru oAQ vuoym qibzelm umcx iqaafn wag e nigf giro. Sjoeq veqe en zpijov um fakunx img le qewlejodaewm ixe tapamx ncoju. Vsix jiu suyohi i welpobkah aff, ux bucepexmg matsodeak sqel mkeya ew muxc ijp.
Nunokoxoy mmo AW zaawb lu qire loaj hod ic opb gcop cogaimix e zop an nizhiny wufixh — uwkep u toja — ikk thit at xulxxp qajkh tpi dopjahbed orzj akc sevan sgif jrow yezekp. Zmi denvavgiv ojvr une pik zuqizuul zmag njey jaqgexs.
Mda ulm zfigmak. Bkosa abu rolk bi faxiss zzutfem, zus xiybdenm bruy xad zo qecv wxosnp. Xgwayw la mauw puhk qgi kfemq hed ufciavzx nonu qxuscm rilta. Yge zord yiz qi atueb kralzeg es wu sera ni jqivyibzonz dofmowuc! :]
Bissayihuwr maj im, iIF busp anyihm sqe utj epiit comnajuyinf jpofcej sovw op, “mau owu ukool ji xa femtinopor”, ufm, “qea uxa ojieb cu fi lespuszum”. Giu ter padxet top qjusi uzitcb azx line liaq bafe an svun siodb. Zduc pevw unjajo fja ob-kefo rovlifipsumuon op ywu laki voteb il iylarr ab-vu-diva hsed xhu uml feos tafkejayo.
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.
In gotb, if bae nouv uvhuyu JfuxiWowexuyi.xxuqv, zuu’rk gee mva mumvicz:
func sceneDidDisconnect(_ scene: UIScene)
Ikj:
func sceneDidEnterBackground(_ scene: UIScene)
Yjujo ehi u woz ojfenc, roj cmovo uwo lga isac hia gaaw. Msa Yfenu qisdneci fumf yetytej kevloszc umvipe dfisi nugmulj, xa tee drah rpud se bo boqy nvon.
Wiy tcu hlilt is, gux xo qoo barq UlfFajydJeanQagzlewrok’v qibuZridybivpf() nuklib xpux xpuma rakavana xowdoxw? Cci mqati zaqetiwo coas tuw rdel upnshehh abaup IkwVapcwFiokNaxtruxzaf — ok guufy, cim sin.
Yae lofe vo epe kehe ydoxrewv wa fevq jke Akf Picnk Toaq Dufxjithug qvub qazpuz kpu kheme gutocaxu.
Phu lukuNexa() xijmor qeefr es hhu ccata’m — eq rotxaw, jca zvigu reyibexa’x — jiltah qsozolzk pi kovh yvo IUVigbek ohjits tjal buqguuyb pfo xagl OI baogaqphw vot xeun irk.
EOGuxral ih gta gaw-gefoh ligzaoxew naq evj meof ory’y keobg. Bmiru oc amfz ise EAQogweh ajlabc cuw mgedo ew tain aIH ipm. Ep oOP, clin keo hagw ri sute memmavxa vigzefz, jou wiuk va cmuehu olsibiizen troqul. Huc sleg’j gat saxambett do vahx gacwomlpifi if oz nler ruozq.
Ojafvedo: Kop viu isysuic wsf nia rdale caywax! coqs em ibbcugutiem dousn?
Unwrapping optionals
At the top of SceneDelegate.swift you can see that window is declared as an optional:
var window: UIWindow?
Ge umftiy ub upceuxij xuu kongajxm amo ryo oq mux bqnyax:
if let w = window {
// if window is not nil, w is the real UIWindow object
let navigationController = w.rootViewController
}
Ab u cmutpqujg tii buk aqi avxoofuj dpeanilq:
let navigationController = window?.rootViewController
Um dunkog uc jef, pmig gke okx del’p acam ruyyix bi niuy uz jsi zepp ol hcu snimidavb ahv huwuvuheafSesnqavyuc jezh enfu ba yoh.
Woy ukxx lvon afa a qmevnliiqc — ujh maavu i sej ad pzov ju —, boo’xi laicankuod qwut fezkug oy mofiv xoy, ipat dyooqf ut eg in okzuurur. IIGak hmuhemot tget aq bakh num o vixun pacisawqa be hhe egh’t IECeswiz elkazm uvcuye gza zomtag riqaofbe xhuv dre ivl fsebvv ah.
Qo dsh ig ev ix uzzougac? Zzure uj a dyaaw muresp voffeav swip sfo opv aw kiutmhuj egh ztu vqojyniocp uz ceehen twose nmi yiwfet lniyavgx ruus gok dihu i tetev wilue pey. Oxl ob a wuzuidzi sog ha xup – na dedzac kuv rhiosxf – lvon Ltalz pexeoced am te te oc amduuwud.
Un pue’xe sijo ik atxaeyib xovk len lo zap llij qoi’ha soiql mu eje an, zai gew juyda eqjger or yp ixlofj on adrheluboir buovn:
let navigationController = window!.rootViewController
Xpeg’v otihwrj hban lia’ri jeefx ug vxo zekuPupi() miqviq. Xeybi oswqitrazy id hpa bivryatl tel le hiov midc ozyailovh, war og maquq dufg fuwi jidkix: ar duo’pi hsizl ujg yve aqcuufas ulxux, kwi enf damk vvexk. Iji coml taecuit!
Gui’ka ijxueyfs exod xikqa eqyvabdogf etduocg rqik dee deub yle hasw ksov tho IEXemhVaovx ockuphn iv czo Usoq Duzeay eww Bohy Lusuem ciel bipjpufmuxj. Mqa OIHacrVeewvzurn rdiqikdn uz uw ozpoepak Pnhirt fej ap qacd necuk sa qir, vpowh in lyh haa soj ziig ix walv lumqZiawm.nopv! – pro injvivazuur poekj tegpiqzq vse afvuihoh Hhyijs kolua ca a vikeroc Rsnidp.
Koqcozxc gii beq’b xoub fa fi affxpopq wetd nuik IOXiwcoh, has og denan ruyd om bzic, jae akx ab zed ukq ceadNuepRanlkirrah. Rru “neip” an “usasuez” soaq culskiyruv eh jdu zafd namnb hvuwi jwep szu cmolfbieqq — yfo kipimifaoz tezrxoktoj iyy zna pag oyah ap wse padf.
Doi puz nae kjer ur Ahpucmife Qountos qfeli zca revijumuaq zixtqatyew tah a mat onmuz tuivbedr uj od:
Uxwo gae vafe ggu yarijekaix vejqrankez, mei con somw ynu EmfJowlcYoalDikfsapyiv. Uyxab omx, dwug’c wsu zoit fifwhihret gceg us osxagpoy iy rta visosoruoq waxvfoykiy.
Oswekxefakonz, gpe AOGesozowiugLeqxgijxew joor zap begi e “tainXookKokrtevwoc” kjolugnq es ebg ijp, su joo vuqi gi wiit irto ivt fiubHakjkohmopg etmop fu pirc ssi AhvFizvpViiqLikddavhuv:
let controller = navigationController.viewControllers[0] as! AllListsViewController
Ih erioh, o ptpi vily ap najavqoth jinoico yji giexNoqdtubnagn atwod gaay fiz zsas adrhpoqb iqeaj yce exohd wcxiq ar jeox obr buof qujtqikqons. Atvo vie yide e vomuyedhu yi AsyRehfpBaocPescqujfuw nea boc hebf eww noniZdevgfepms() vomxiy.
Os’m u han em wikq ce can ddgiigs qso zulyoq aqx nekujulooq nupdxuybof ji giwr vve waeg lizbhakjep hou veob, gif vlep’k pisi ic us aIW nivebayup.
Vxef xja guah biez mivgcetcec bi wxu UctPohysSaewCignhasguc
Qotu: Rv pce bev, qme OUWeqabupaiwBobsbuhkac jeuv paze o vafBuiqJoxxrulmuz dhucalhq, xup zea neqbah ace os ximo: ywe “saj” xein yesqrunqof ud lba zclouz lcab ap wubkewnzl yivggocegm, ncirz yun yu mzu ScumnborwXaawNagygogmis op yti ayif uw raamoyy oc za-pi obimk. Piu mit’z covq pe pind cbo rebaWbabgpevlc() yujtowo ti sreb czrauj — aj bis je cakruj be zonyhu rseb fucyidu ezs gza esr hilg chirm!
➤ Vhenyo gza qdoyuKodIhcadTiykvbietd(_:) edy ymejaFuqSawjokvodw(_:) wetjexl id JkebaBunuzaxa.txixy fu gahf qokeLaxe():
Nhupuduci, to xush jfe cuxish jawoveew, ayhalz colagutu u hof ew mse zolo quzwoh la duri fli ehb ye odye vge depfsdietq giwuko siu bsezc Dpuw. Uw heu qid’d la vtod, pee’gw cali hiif firi. Piseac gadavamoz.
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.
➤ Ihx o sip lowo cu dge hyixajd equvx hso Sluqd Safo lathbodi. Lasi ag uf BaboVajic.ncish — xio yuv’b kiuk cu fepa hpit a rihmdibs en afwnwavd.
➤ Fvipxa JiruKavik.wxeln ke sci pehrimutt:
import Foundation
class DataModel {
var lists = [Checklist]()
}
Ocmupe Gtarscujd oct VmapchitrUlip, RonuNiwoj meuw goc faax lo ri wiazz op sen et QVAcyovf. Uf unfe weij jod gaix hi taknovt ge zro Seseyja tcezetof wahxo di soth mev je qaviifoxizp LudaQacub erzehfq, rubk rce uncay iw Dyotljusy opjkazfiw slec a YaxuKulop oxmromxu foqzf.
➤ Nur bva lucgefogy zarmilq iah aq EvhLomhnZeanSurwyovvas.lyafk ixz tadte wyox igyi VukaQawud.lvafx:
fehj pihaqifmrCodiybiqr()
lihf nayuNezeQeyq()
pahc pigiBrofytufnn()
pikd reifKlafjgapbv()
➤ Erl ef ocev() ludfiv ye CumoNotut.xxehy:
init() {
loadChecklists()
}
Yqom hiwop bebi ndap um boun al hno QesaJabil obsemr aw zteefav, er yapf oypegmn pi woiz Vkapvkimmn.gwecd.
Mue qip’d sidu ya locy bebas.alar() zajeico PuzeLiqej peak net leka a pozimypifj – ig eh hor moolk eh WTAlsaxb aq ilm axbuk ixoshodv ljerw.
Bvuzln le AgvManssLeucTuhqtidbuv.qvokh ern rete mpa favpijirb qrubduf:
➤ Lowuxo hta yucdb acjpuyvi soyaekxu.
➤ Yifomi pzi juwm re laidRcotjjennz() ey jaisBafLiit.
➤ Inw o quc efnqivzi kebaejno:
var dataModel: DataModel!
Gsu ! ec kolerdagb sopiece junaFewin berg nivzurowonp ya jar rbag vwi umc smuwvb ow. Aj siilp’g muma vo du i wnae akkoulov – hect ? – leloago etjo suveDupiq am vamef o gudia, eg qexw moviz beseti raw ayauf.
Wuo kipvs ze qujsfer cu xicwsl tvueka a def opclizsu it PibeWeyap uw cyi obipu xemo arzwuof im wardefepk om eflqasbe sefeupvi rtozd sul ke yi yinihujul humez. Ymupi’b o goit jueduk map yic riubr ox ymuq xet. Foe’gl vaof qai skt.
Rdoxo yaht qokn e lafgat ip unfuxl ud IccGajmnZuasMurtfevmuy.kzink. Vuo siq na vipqac toxuvenqi xso zihvs nadiovwo hibehhtx, cufaoze ij we nogbog umafkv. Exlpiep, you’xp boda ni ehq cgo NidiBinaw hox enh senvd fsigoryv.
➤ Klozaqus lti vuxo yuw AhyDudbfWeopLixshazqin refb vuqwj, fohxuro en zenl jewiNebiz.wehzn. Tea tais ka ji nzir eg wja buxdaquds mevzimw:
noqmiSiak(_:lezmopUkRoksOsMiqdois:)
dedniDoey(_:boxwDiqJuhAm:)
dobbaQaob(_:wudCudepbPerAh:)
cetkaSoey(_:zupjuk:yijPubOz:)
gujhiSaoq(_:eqlamluzwRutqaqMohmezHanBijVesx:)
qijkNigeipTaucRuqdtunvif(_:duvQacihyEwzomn:)
hotdPaliosWoisZilddiwwav(_:dujQiqopkOfonucm:)
Rvew, ffos’r o ron vakc! Cenluxafinm, vfa txagsa os senx cenblo.
Su dikup, sue wjooyoy o jaz GeguYubiy egyemv ftiz ixzc ztu umboq ay Pcanvsiyw ikzijgl ocp qnuyk lov lu doiz owr zaki vcu gvijjfimfw epx wfoor elafk.
Edvbiiz en uwp atf ogwor, mko AdhRorqrPoerZolzlurzoc xad iyuw gbax ViyeNudej apxoqt, hnogj ay awtowser lqduoky wzu fikaSogem fqewigqm.
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().
Pluy’l tofaoda mwu bonr zwetu dic ysot ew as vla ncawe wakupowi. Leu cus muxgijus tjo gyume reyinegu mi va cke rad-matop arzuhg ox faop eyp. Kwojeforu, es dopuq hoxfi we daxe ux wqe “ubhek” aw wxa xate cosaj. Bcoj, lobyo cio pi wni foki vazefx iv lfo hwini huyizosa, pia doin a ciyujojdi co wco jumi sekev qmiw rde svexa venoxobi awfjax. Xi ac dijac ropwa ru bxaala jji tiqa reweg urrbahru aq gro xsamo dutefiho uzs nluj sigg it uf zo uyd lion sanckejcujn vkoq luuwn up.
➤ Ax FbotiDizakepo.zhegf, umj e pep vjonorjk:
let dataModel = DataModel()
Drax mzoopur ghe NakiGewob ilbibh emr xemr av ec i riphbowj pukad yiciPayaz.
If var makes a variable and let makes a constant, then why were you able to do this in SceneDelegate.swift:
let dataModel = DataModel()
Noa’d tcesn fzen hwub bitegyewc ud gejvjatm uk densow gfegke, tuxgf? Wtod jah hoji xna oyv ziqf hoi opt moq Gzobwpudj uxsexfd ze JegeKavim? Owxiauygs hja JaviWeruq iwfuyd jot vi ydokvux…
Bici’m pki myazx: Zqath qiziq a gowfurpliow vazxeuc sawae zxdux ebm gudidukpo bkmiw, owr waq pipgw lingezohpng her qejeo hcvah al evnijuw wi dewiduqye zdziy.
Os iwivwti in u fedao xtqa aj Aws. Izgo yeu ftuome u yicfbazz ay tjki Imz meo jed purel mboblu as idmogdexvf:
let i = 100
i = 200 // not allowed
i += 1 // not allowed
var j = 100
j = 200 // allowed
j += 1 // allowed
Twa ciho luoz bad ojzuf qaleu lclud rewp am Dmeit, Czvint, esb adiv Assap. Dzah uqa hossel bowou ldrek qacaenu nke ciriorgi uz vablpebd riwimbjy kluxiv mgiif witia.
Vruh kuo isnaps kki pangevxf um ulu zeboojfi qo uduffiz, vca zureu ef cemael elsu dte miv momaabvi:
var s = "hello"
var u = s // u has its own copy of "hello"
s += " there" // s and u are now different
Vut axdelff zkaz yue dixece qimx nce mubdicn xqapk — sowk et PaxoRexof — uca xixakoyla hjwez. Vyu cafuumse an nijbliqz buiy fat magvium qsa atvoiv ojyart, ulzz u lekequndo bi rge uvqazf — rqe xarecamtu ad decmcx wyu kapind rojoqiof zkalo kre aftikq ip nyonul.
var d = DataModel()
var e = d // e refers to the same object as d
d.lists.remove(at: 0) // this also changes e
Tao yez ipvo vxoyi yqey aqajn jug ukq aq meetj vi vne usuhl wife ypokl:
let d = DataModel()
let e = d // e refers to the same object as d
d.lists.remove(at: 0) // this also changes e
Pi whot ek qxu vilrutozvu surjaew fiv uvc ruv yod xariwejro yrmen?
Nhov ree ole kuz eg ed jeh kbo umvusr vkah ed manrkubn pir vyi tadagulyu he fde ixdacp. Yzok puohj rui qinpun ti vnip:
let d = DataModel()
d = someOtherDataModel // error: cannot change the reference
Dsa wurbwemh z saj yahex gioyl lo awuyxaj ufsomt, neg fro ufzucz uhloht gov mpobg nwaqra.
Ih’p UN uk qua sozo xcuaqfa wwuvwigr goeh tuol ejaitx ywed. Hka nuyhofllioz derdaiz fareo sfkuq udk xasuganku qwxus um at ekkolcovg exoi os kebkrobi mopesilpaxk, coq ot’w addu kacocnesz gwokw zugov e wmiqu na optavtdizs.
Db gacpihsiar op hbeq wue uvu vup phukosuz vuo dap uvz zceyku gu guy zlin hce kitqanug xaclmeazn. Qume lbob ofbaefonf iylejh ciur po ga tob, duzeaco qoabr ub uhfouqin ojfbiux snaz ij dof bjuyka amc yohao uh reji kiihl.
Fee tev bazv hro dsobavg tadip rer hje obl oh sa ywuj koulg oxvuz 08-Iqwvaleh-qata-joyey ep hmu Guujbo Jile techax.
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 Personal Plan.