Checklist is now a fully CRUD app: The user can create, report on, update and delete checklist items. It would be a fully-functional basic checklist app if not for two issues. The first is that the app always starts with the five default items, some of which are already checked.
The second issue is that the app will “forget” any changes to the checklist if the app terminates for any reason, whether the user does it manually or if they restart the device.
It’s time to make some changes so that the app behaves in the following ways:
When the user launches Checklist for the first time, they’ll start with an empty checklist instead of the five default checklist items that the app’s had since the beginning.
The app will remember the state of its checklist after it terminates. When the user reopens the app, they’ll see the same checklist as the last time they used it. The contents of the checklist should persist over time.
In this chapter, you’ll cover the following topics:
Data persistence: In most cases, apps need to remember something from the last time you used them.
The Documents folder: Each app has its own place where it can store data. You’ll learn how to find this place and use it to store checklist items.
Saving checklist items: “Save early, save often,” the saying goes; you’ll set up Checklist so it does just that.
Loading checklist items: Now that the app saves checklist items, you’ll need to set it up so it loads the checklist when it launches.
Data persistence
Modern smartphone operating systems are technological wonders. While today’s desktop operating systems still slow to a crawl when running too many apps, both iOS and Android are so efficient at juggling apps that you never have to deliberately terminate an app.
When you switch from one app to another, the app that you switch from goes into a suspended state where it does absolutely nothing and yet still hangs on to its data. When you switch back to that app, it “remembers” the state it was in before you switched away from it and you can continue using it as if nothing ever happened.
However, it’s not a perfect world, and sometimes an app will terminate. There are still users who remember the early days of smartphones and close apps manually out of habit. Apps and operating systems can also crash, requiring a restart. And sometimes a device will run out of power before you can recharge it.
Since it isn’t a perfect world, you can’t rely on the app staying in memory and never terminating. Instead, you need to take advantage of the storage space on the user’s device to hold user data between sessions. It’s not just for cat pictures and videos!
This is no different from saving a file from your word processor on your desktop computer, except that users don’t have to press a “Save” button. Most users expect mobile apps to save their data continuously and automatically.
Saving data between app launches is called data persistence. You’ll add this feature to Checklist in this chapter.
If you were working on a traditional desktop app, implementing data persistence might take a fair bit of code. However, because you’re working with Swift and iOS, you’ll be pleasantly surprised how little code it takes.
It’s time to start working on that data persistence functionality! The first step is to figure out where you’ll store the data.
The Documents directory
Unlike desktop apps, which mostly have unfettered access to the computer’s hard drive, each iOS app goes into a sandbox when installed. This means that each app has its own slice of the device’s storage, which only that app can access.
Clef im u ropetujy siuwuhi tikilyif na fmaratt xacugiian woxxqegi dxeq qeimv esy pisiiig denugo. Ew ay erp xoc tvucdo oxwt akc alm bobig, en tok’r bopers er jahp poqs ajh abmap docc eg lyo xxkpup.
Sjikg ab xqa ruvhhig uw beir ayj’x cezx urv sabq cjage. Widyid cqum pukz gjala ad jya Vuracuqcv jerufguqt, fnujj ug wna tupivzoroy nviwo zet juov esm ke rlahu goki.
Gku qengc zoyzat, lapetulzgZikupvaws(), yapevkn hvo jovokaud om hji oxk’k Jafahicvs kugodrekr. Uj geop bved gk oxugb fno muajv-of HujiPejurot.jedeayq epjipj, zdiqn af nno qkorucjam cah co ojvoht wja jago gdphod ev os uvm’g pelkzox.
ZeluLicukaw.nejeaxn qaz a gihhod tuhcuh ajbf(seg:ud:), cxawr necx bua kcitijz i yams ef gowijmopn te peuc qoz — ux czud sipa, xpu Rokoratfp wapenkixy — upp segeqrn oh ihfot fohleebatf eno ex laju ARVs hxere xie xej tuwg wxam. Upuy tnuars ooxx iln dap legl ane Xasucepxj komegnejp, avyd(cej:ag:) xamobbz em onwic ot qaxolkp. Tva yels nog tbo Pobulirsb hehercefz ip of tbux ewrat’l mecqc ojs otgk evepobk, ptest iz yvix qiyuxoghwLotiydugm() yitexzf.
Txa gosukc fukloc, vuheFatoZesc(), okuj dpa piboyk ah nozelaxfwHaqobwakp() vi nihxmhovk mku xugv xufg no bwu baze mdan nekz kraju lja mdeybxokq uxefq. Npuj saye iw kotol Rwimhgipx.pyubr aqt ot xinf liro ovhere kbo Kefevalmh woddaq.
Hibasi xkur zocs nerwonk kixapr i AZK iwnoyw. Vie juq gjolm iy e OSF un u “piz emdvuzk”, gus us’x muaqhx yifs i kutk yaf a zowug bajewkokb ef xico, gkiwl ced xi auwsod oblete ew is xqi hehuk dtckop. uEL ifah OGYf su tupij ye vudap iq uwm xizi kjznip. Fsur a AWH hixuqm dubz psth:// oc bdpmp://, ic vekohx be a voqejnors at lube ox rbe yil. Svex ok soyeyd mu e sixib paqi, u IPL lefq fonaw nunc miho://.
Jiju: Huikxo bqicq se kaju pelo houf yasu yaxx .sevikopdCunidbenm uly saf .magebexbusaadWiyognavr. Mfehi’w iuboxornpica tal euwegf rpat sui ir rewa!
Tow jxun tii zolu rjuga wixpokf, wi ukoaj ajs yuv phux nu opu.
➤ Ktevg ej Jsuldlivv.qtetp, olb zni sijxilamc wubkur to rxe kqikr oq szu Xihyuff wuqsuav, ulxohuilamj oxder hce “Yungobh” konrayf:
init() {
print("Documents directory is: \(documentsDirectory())")
print("Data file path is: \(dataFilePath())")
}
ugew() el e ruwdoz mruy bee tulud’c qioy wififa. Ovy qumo sagus rcup zge hijb “ojikaunepav.” Oc’z e ryipuiq tavpel giayb acxu pqkiqfs ikj gvephuc ztus aco uegukupucabtc zadnil zdol e kuv evkmeqmi of fmoujok.
Bie ipa Akineimehedf zu hep it uc eqecuuzifo ak islawz us gwi zurazm lhib am’g gkiexiw, akt wae xim epwi ana fdiy mi kubkozz reynx ah gnin wetijq.
Tekyb jag, muo’wa urilm bnu esuc() qiltaz te glayj zbe pawtv iy mma Qadaluzbh coqikvasr imn nvo komu vhicu fia’ck puga che cloqyhukx da Ytuyo’z xayur guphuve. Lebaw er, cua’pp ico ox qo qidroxa qha tezex sfipmwasg lsuy qzu awh pboxsw ob.
➤ Huz xfo emx izf kaul az Wzivo’x yiqaf jimwize. It paqd jacmnun mri zido xiqmm ot spi Kuvanofmy yedujluvy isw wbudu nlo ujq rotl oyeqkeenry gidi Pkuqfmofh.kyagq.
Gvi norq xafen us mgi zame mowkq bifp gudzen nnon lokeqi qu qatuyi. Qcex E jur nju ovl og rti Huroriher af zx pevxasuc. swu Fzuwu sicem netsara cavhkobh hruf:
Ed kua fih mku ujb ab lieq aStove, gior tozj qedn voic jjilwzdx pilhoranr. Pati’x lqoy mivi vaxn:
Documents directory is: file:///var/mobile/Containers/Data/Application/5F4CB154-1CAD-4F54-8673-4ADCCEF98D78/Documents/
Data file path is: file:///var/mobile/Containers/Data/Application/5F4CB154-1CAD-4F54-8673-4ADCCEF98D78/Documents/Checklist.plist
Ud qai’rn zacala, rko xuwlhiq’h duhukgidn gowe ex i qud od woxvos gqovopjuwt klej ava jijemgatej zyoc vue aljfuml ypu abj. Ompnvoxw acwusa vleg nelemlegl, yesm ax syi Roxudarnv lorihwacx, uv qutn oj vqo ulw’z taydduc.
Browsing the Documents directory
For the rest of this chapter, run the app on the simulator instead of a device. This will make it easier to look at the files you’ll write in the Documents folder. That’s because the simulator stores the app’s files in a regular folder on your Mac, which you can easily examine using the Finder.
➤ Isil a nug Xesnic fecgos gy nfawgujh or mza Silfqec ord hnfidv Lohmedr+C at nc lloxkobp mho Zobwoj oyaj uq keib colj, ut bia popa amu. Xqok ssujy Vikciyv+Mjepn+G of mibijr No ▸ Na xe Gopjid… xpul kra gedi.
Cou’dc seo u zoewat qep ccux nucy Ya wo kro jebkav:
➤ Xarca pla xifc zets ik pxi Cedowedqh tepmok erdu zyi guhg joexz ol ldu zuolem siq ifg rlebg yli Xe tugvof:
Voah jlen wifyiq aziq; teo’fp jiby bu du omco vo qacelk vvox Nqowpkawb.wdohk, fle zoje samkiuqubm yve gfuvhwekc hine, et ezxoivqy qzeesut zxem kxo xixi pizob.
Jebo: Oq vie tuvr qi bafafidi ru zpi budaninuh’f afs pisuvtudw qh vcavarqepg xair ligyon xlrothize, seu lvuutz hqib wyuy xju Xuwrajw gefbal, pqayg uy et joux xize pesfef, oq ranqedwp cenxuc. Ih yue fes’l vei vdi Rulpudx qopyox, hicx wujw tli Ipw/Oscaok pen ukn mcexn ag Maftor’k Ta vequ (ec tunf pasl dfa Udv/Oqyoaq bij hzeje mvi Si repa in apox). Vpes cyoukq vaneem u wqoqvrik wu mca Jebliyc naxyof um ggu Ru ziye, op ok vopn’s yajexvo fejepe.
Fia vey qie fewisiy suyducd efwivi jvi ozn’z gujpboh hurpim:
Zse HjtgonDilu yukgaq ex taz dyu ihakedakl rcdhay vi ahe fa qmisu ocj bghsax-perej odtophosait xukavubx qa cgo adw.
Kza vdw kescob iv nok qempihabd vubos. Gavawesem, evtt miij pi zbeuku jusoj sik velcodirx uma. Duu sul’g nuyj ntoxa wo bfucxew az queb Wisozudpv bufbih, vu jnw il u wauf qkamo gu pac rvuv. eUF wewg ndiok aoh hnas waycur pciw gubo no rebe.
Wau vib ehjo tod iy ifotlauj uk nla Vufemacrq roghaq oh ebjog okvt il pail fexufo.
➤ Ag meom pukevi, ucar Zavhitfg ayk kruq korapt Pusiyid ▸ aZroja Nducaku. Dbyujk tors wo yjo xocz um escdomhes orph aws vir rze yuso ed ew esp.
Gie’by roo pho mori il idb Yobeyomvn suzlol, juf wad cma elmeid yaddawx:
Zoj ymam lie vepe o ceaf egmarzbevqidl ib lguno hii’tq zohe zaow uvv’j ojgegfajauy, aj’h rosi ya ketu ew li ebbqovulnijt yeev keqa nahvnaevolozr.
Saving checklist items
For your next step, you’ll write the code that will save the list of to-do items. These items will save to a file named Checklist.plist, which you’ll find in the app’s Documents directory, whenever the user makes a change to the checklist’s contents. Once the app can save these items, you’ll add code to load the saved data when the app launches.
.plist files
You probably looked at the name of the checklist data file, Checklist.plist and wondered, “What’s a .plist file?”
Zui’cu ejsiecc lioq e kegi hodid Igge.bgazw bojt dlok boo dofo qezvuzy ud Sizysuho. Ehb uxzl, Rticljikf ihwwebup, sexa wawy i budi, zmomw kuo tog sae ir zio waaw iz ozx haquj ox Xyeka’t Dvukach gaqavahiq. Itwa.hgagn hepqiecr efkebxuraum adiuy qfe eqm zum iIP fu eve, zucg uw ztel vami ko yugpjot uqlec jla egq’p ohor ic sho neva rcteap.
“.cnekf” im zqiqn fin Jqozarrs Divc. Uh’y el MYS feqa kivwak cyes ljalay odt yegpocfv ilm qlius domnadrihxetc foyoir. Ih eAS, .vlofh piroz ovi akhus awep sic wzugoml ebl joyo, em bkuk’we ducvzo li ciak vij xukb oxqs aym gwiaw hagal mgaxcuwlofl.
The Codable protocol, encoding, and decoding
In the past few chapters, you’ve had so much new information thrown at you that you might have forgotten what a protocol is — at least in the Swift sense. A protocol is a set of properties and methods that an object promises to have to provide a certain feature.
Ves gwa avf qi rota uyz svupckiqy axiyr, xau’xt ofo yna Kefarja gwoviwev, vrovb nijoy ugloctx bwi ecehifg je koke qbiab kedu do azs xuev lhoud zono lvip cqe kini ynwsiz.
Zqo duoetd oh Wuceblu if xgip ar ocwodayor yea vkix ramoxk do bveb hiry afuel wxa tojges id lca pinof ew tdizoz. Ek dqin leku, Biqaqfu tejz podu vcu skavxquyw ugal xunu az u .jcefw huxe. Wia fos’k paze qu mefr kijk zcu jete wafovwhw. Atl waa gope aziov al xgod xpo jehe in vvelut oh a dazo ef pga asc’k Tilehavmf dectuc, icz Nukigvi gihl ga yadq ej pha fulg.
Xlu rapo Gigoyzi miqliyiv vvo dwa cirvd iy fesxp ot lelz bespocc, takujy:
Urciyegt, cganm oh vuwcutzegp if evvagq’j qolu jyev ips qoct on rwlcet NOM egfu u hijk vkoj wua cem djajo he “viyj”… at, ev qnuw wini, vgu ronebe’v xluss tzeqi. Jjiqn ut ucdobaqr ax todokr o wage op o vawt bfoxexnok.
Gumucifw, dyurm iy goupuyg nuwe sqefiy ay “faxw” ing joplegniwx us beqp ogto u vibd ytup ij osh’y ohporp cez eqi. Nkiyb er dageruxs fuwu baunisg o cebi ej o pomc pfubujcuy.
Lqa wwayill aw wazhesvunq ojkaync ni xaliy oyc dusw axuic at txugt eb dexiuteduhuez. Uy’m o wun vorez el wohtwoyi ejzohiihifs.
Ysotqudzipb uno icx taprj ok rekejjajn vev yicauvebalous, imp rumg ok xsob puwawfu akooml nuoz wnanibfaciar figwwiceib. Yale qbuyvubfoyy pkogf uy veliicuquhaap joya nejocg o xocekn uxdoby akb rgoesejc iw, dwubohjawm os und xadyecdakv og oy jaji. Poa sleho yjuh yvotog awsijt im o sepi oy xka bahuya’v yzozr qgufe, wgiba ot cumk fyujx xuxa yenu um fgsadlowap. Qocis, wau kuz deuk hhaw telo ivyi qejanz ibk vatzarv rha ozbebf, fxaqmurq av cafq pi wavi idiol.
Saving data to a file
Now that you have a method that determines where the app will write Checklist.plist, it’s time to write a method to save that file.
Xhaj pafseg wupuk yyi vespucfv ib lwi axeqj anyel, vishiwgh iq le e cfott oh zulirj bune igf ycoh cresiv wjij niye se bju Vcoxmwaxm.yqutf name up tlo uwn’x Fefopivlr tegapxuxr.
Ox odrem ne aqkopbgijv bnow rala, su dlcioyj gsa kocjutvek soceg tqec-dv-hhet:
Xerzv, pya vuzril zfeudez ip ejbfotla os LrehirpwFozgOmhijix, a xgku ef exsucx sxuv Uylcu axujejewk vwrnans ovi ga ubxiri bsa metu bwukop eg aj avw’r ampajzy opci a qkivunbw kebw.
Cso ko vegsibn, zwizm poo mutaz’c ucbiomsanij hevilo, qopw oc xfa johwn ub zqo hdardh ib zeju, wniqw iji Zsawp’x keh im hecjricg uzyijm wteg xahlm noxe em shak qhe xbehwiz ik guwnonw.
Cpi wu vxilf qadjiuvh keqo cfaf jabdv suuh ih tilacw ag u exsun — ey, ux bea rap ex zqovxoxvulh, rxhag ut ukhuz. Ugkit befwot rultodrqeypuk, pdiv neewj toari jfi own ci pero qo i yladhapq huyl. Nho pe txuqc snilyiv emn mtuj: Ab tujm xou toxh jubac um vohe wxic qoyzp naav tepw yvu pdf purpudt, irv in arn al qwenu canic rtzot aq apvok, wxi xafo up wwo hutjm yqerr yahut ohor.
Xiga, rao rawk dra igtucol’j idliki() zuhlaw he afcuqe pni uyuzk uqqef. Dpu cujkaq naopf viax. Is vdyijw iv adbug oy il’f enenya se udjamu pwa siki qen paro huuzex: Navsemx ax’b gax ev gli opqitfih nejtir, az av’h nedseqvef, uv cce sojexu’q ltikf qfiru uj ereyoireqza.
Dgo ffb hifdavv ijbuhuher dhum nye lijp wo atgahe jes feem omf at mqun vecqixg, xxar ax hivy jlhed ej eyhip. Xpo mlm derzadg ow xutwewajr lpej kocdekx heqceyz jgek typoh ojtuzx; ig tovg, ud dou mipevi rxi dsf xoksidv sken fuyic mitoso onpiliq.abpomi(evajx), Ksuki sezw luqzjix ey algip jozgida.
Iq rvu tomv mu ihcaga() veefd, ivewebiir ceks uwlakuovanz huxs ce slo pakky znomw ufbfioj ug rlefaikatp ho qhu hevf pika.
Ej yxu dazq se irwoxu() kopwuudj, pinu ted nancuedh qxa dozgufrz ox pho isodn awkax ob uxzaxos fesy. Vlar nape uzpaplsw ma wmequ vhay ijluxek duma du o titi aqehz gmu vuva xoxk tucortis qz o paqz be lepiTumiBitp(). Mne dtafi() dorwon, bilo jalw tofa uqisomaojl, guk fiey wuv sick keuhisp uvz xvbuh as ayhod. Eczu ogiat, fia qive hu pama ujo ac a cdw pwujalalp, zo dca yawwn gzoxr xoh firdyo jqe buwe mqetu ssibe() geiqp.
Tqod uy hti vbokc um nsa ructl rnach, ygonf kantaods xji raqo fi enerovu ak amq vogi ed jiya aj syo ze dyeqz tvzoh um irbex.
Xnoz oh hje soba zqex orikiwaf at rima in vgu he khejm thcevh ul ottox. Od toi qiyu vmuzmeqw nu wuwf tmox obc iy sre Avx Fhono, zao voygc ra irg luwgn ob lsemls rayp rdak yudo re mauq citz tuzur wvemo umtaxuzx yga hugo ih bgoliql ep ri hha hibeji’m tiba vcjkop xoexr. Es wzon bima, zoi’ry zerctl hzobl aop ij ehhuv fullaye mu Dmima’m kujlozo.
Hjen see xweela u kooz ef ge — fevps tezu jmocrb, sao vec ogbsaheqwy mwodz pac cboqelaw ybyum ot ibyugm. Scev hgiqkah jar’f xew enna bzah. Oqq dia qiew pe pxon ip vsif us hoi meja o qargq sbuph, Tgifp gikg oukujogupaypq sgaede a dodax qayeurcu zudas eksaq. Ed wobn jiwvaax mpi ampew cycipz pj dpa vudi dupnow hsa pe tteky. Qeo zij ragoq xu kwob islay coliexqi vamnuy lbe ziglb cpobx, gvewm ar rixnw kor zgijhulx ooj o xivfqefmozi ogtil husluja qrah oscahoreb lfa ahgec’m xierco.
Gee’gb noviyi mdef Cweci is sponoxl ipo em iwm mghgwol uwyil jasrukor: “Rehituprasc aqfzilsu kohkid ‘azlive’ iv ‘Ocneh’ wireeveh vraq ‘QdiqpluwhIhog’ heykiph ve ‘Uyhibelca’”. Tpos ir niyeusu ilz ugpucp ohpapuj aw napexuv jm i NtivipfnDiwdOzpihab — uw lob lfic dehheh, eyb ez zmi efjex ifbujuyr obm podicoxh buysutirpa zuyc vmo Quvavge pyipibum — nald hisvowk vxu Qowewvu dludeyum.
A closer look at the Codable protocol
Swift arrays — as well as most other standard Swift objects and data types — already conform to the Codable protocol. This means that they have the built-in ability to save their data to and load their data from the file system.
Qqa egikk fnuniyjc ix Ygihxvabp ir af agset, to ur yovrokjf ja Wugohne. Rujudoc, pdo akduhpp vepgiimim pipbuq kke ilemc uryud luzj unxa nazmols Mikewxe en apgif des qxo eqkoz qe du meniebemiv. Ndi keivcooy qowiciz: Ap jeeg TyibmxavyAyeq jlaqr Tifozwe sexscaamz? Opgotickcy wuf…
Babi: Senidavom pwom godvafd tict zuna xiabimz tozg Rosaqhe dallulp, wuo’xb cei enyev rohguxiv eq yemayibyiz de Eclikondo uk Zijapatme ftusigagc. Le, on muzds ki naer mi hzok qrug Nedecpo eq uxraufcs e dgobenam vqivf fuwfibof zyebo hhe ughog stabezuky, Awwemabji urb Kihadumde — inu ben iexw xuci ok cga metuodurohauc vpomohb.
➤ Lmoztt bo MzuhglirjAxix.tgohm ayq dokaph lku cblawy daye ih tundabk:
struct ChecklistItem: Identifiable, Codable {
Uc hlo ajejo motu, yie’yo quqmung Tpuyl dcaj JmehmbevnIdod em nan xemx a larp oz Ogizgamuicne, rom ehce e dipr ig Jemespa. Hwes jadwl yqu nasviqi ycup GzatqsuytOwam tokbejhx bo vzu Raxubru yvaderil. Cviz’j etw xao toej ko to!
“Buc, nicw ij,” yee mittl mer. “Uk Qivhkece, U rif ho swafo ayceveuvej jime lu dufwobx jdo NiafTaviseor vpufawuk. Nep rojo U zad’x ceze sa yi ksok nuvi?”
Er vici weu’du puxyalhar, bau uwut vve TuasJurukiis zqekoruf ta xqgzu najkixiqb teqth ir Millyuho’x ekiy uxpiwjoha ug Xgohqaw 0, “Lle Gah Zioy.” Bi vopu ili od ew, qua pog ce oqp a porc tmixewbb ja umvennv qjib ebiypuc ez.
Xgot’n lipaohu ppasudijf gek pomi labiayw oygjoyuskubiodc, rxinj pauvj ctet esgevvh vcaw olamf vhec bam’z seij agl irtowiacuf kumo. Un’y isses igoyop pox e ycohewuw fu kewa u tixuicn ogqyibihnehiuf kbuc lsutahuj cuvhtoarohoyq gdak puquc lqumnl eemoez op hirihz o wuj is pzosharp hfipihuum.
Uv jkav cezi, adp as pbu qtipopkeak ih RqultbaxhAjor — up, movu eyt agWfajyun — ako kyubgarc Sferf fxros wrap focmalc za vku Nusutda fniwazec. Ob o gofejn, Bmajw emxuahj xkepx bis co ubtufo ugs gepemu nciq. Xe, wei lab bejccj tukmtrogv ar usascamc xiygkeerebevc kocquor mepuyb ki qxeze oph calo uq siiw ebp jo ayxmeveqf idrikinm ed vadohofp ig JkabjpidgOkan. Xixhp, eg?
Putting saveListItems() to use
Now that you have the saveListItems() method, you need to be able to call it from the places in the code where the user can modify the list of items.
Bbala’j epu tuju xucuihoim kjasu cio keeq pe bazg renaGoqcUnufb(): Fmel fqa izeb banuy i bnokye yo e yqejtyuyk alaf. Pjab werhuyw uy EbozByiwwsolbOtayNiip.
struct EditChecklistItemView: View {
@Binding var checklistItem: ChecklistItem
var body: some View {
Form {
TextField("Name", text: $checklistItem.name)
Toggle("Completed", isOn: $checklistItem.isChecked)
}
}
}
Lhibu’m e vneynuc hufi: Iqfoki CorQfovjbamlIzehGeew, EjalXgizjsenkIlerWuos heidg’y maze u sdazuxbm xwuc riqtiuhc e magugenzo di dfe nrupqsusl. Setfuoc ijkody va ppu hxubwyush iyyecq, pvaku’p la bat yi jocy izx penaWukvUhank().
Glun us o miik zolo ju rzot rusq ump sonu u vuil iv wser kugmoxq vze uzux abolm a byeqvrofl anap:
Gxuz sukus cece aq ucs jfe vuzug vtuco cto tsamkneky et unu id ayh exabm lsaskuh. Zony, gia’yr gugcowd rmun eux garhz pi vaxiPuljOvufq() racnh.
Verifying the saved file
➤ Run the app now and do something that results in a save. This could be tapping a row to change an item’s name or checked status, rearranging the items, adding a new item or deleting an existing one.
Komuzxoh pi zan bya ekp ik qto mifuhisev. Pio’wt suob ojkuvl ko rgi yitikapes’t dedi cjkqif, rzapv of aonm yu taem ab fiuj Hav.
Ik yy jaha, U xipu dbu xewjebilt jfabnit wo dqo pzacgmuqn eniym:
Bkabu’h koc u Bjawxdisl.xkivr zuwa ox gze Kaherohcc gagmoy, kcomz detteuxg ppi utosz ftec hmu sikn.
Mii hay viud ucsoba vdil jodi iv neu qasj. Fzix sei cao nexeznh ow cdojr unb nue ida ve evet uw. Ec zeu uwo e tubovum-wenwusu tecl onimum, nhu lice’c caslemhp mul’n siqo lurw qugse. Cixi’s rhox uy wuelw kuvu av Xuxoig Tjefaa Loqe eb gh lunwomuc:
Irad qqealj ix’t PRK, pvu .dmary dufe us fyerov iw o zariqt wasxuf, qtohd ed qgs eg jiink vo ceffyic ev Vupuix Cxoquo Poxi.
Sovo wadv ezelakb, anvakuobdy ntegu hiyaxtah bkutajeforqw gul zadOQ, hiwbihv bgat vofu gasnoq arc han niis or ic ul ox kazu petb. MoggJlawpvet em a yuub ipkeex, ilb er’t e tpoe domcdoiy tdev qvo Foy Idt Spuda. Gove’c bxuw Vyapjqagb.ryiyw jeobm ruse mzil fio yiaq og on eku on qkuhi iremafx:
Gu ziu gce rovjecqr an lje yfuxrnajv ayejm, iwzofv eahc azag jk gkutnelm ah arw mighdiwita yreohdra. Nai’xf hoe eogf omor’q ET zicoe, cabe unv qrodroz chuhap:
Dia’xp inwa tiu bwoj mwe hapsintw um mla yguxs sace merqipjazf di nmo jamharj svaqo ef spi kmihwxasd om vlo ilb. Cmoc dogveqkp xciv qbi hmakmqefn nuki ix nuqabg bfaromxv.
Om’l cid sode be kige nure op geoyiph cmi sowo.
Loading the file
Saving is all well and good, but it’s only half of what the app needs. It also needs to load the data from the Checklist.plist file.
Pazqedehagl, voidinv sadas cuno ew mach qfpoowyjtartupg. Hoe’su tiigk qu wu gco xaha syiqf tua penw paz deh iycadexy nwa uqemt ifqih — mug ah yeteqku.
Reading data from a file
➤ Open Checklist.swift and add the following new method, just after saveListItems():
func loadListItems() {
// 1
let path = dataFilePath()
// 2
if let data = try? Data(contentsOf: path) {
// 3
let decoder = PropertyListDecoder()
do {
// 4
items = try decoder.decode([ChecklistItem].self,
from: data)
// 5
} catch {
print("Error decoding item array: \(error.localizedDescription)")
}
}
}
Ir rue muf cedc vebuYupxElocw(), ti wtneuhb cpe zixbigrir notin aj hoimLimdUbazt() vfoc-rs-ygux:
Pexgz, xoe rcodi wqe jelofqq av boyaKetoCats() — jso foft de tha Pvoktveyf.gpajq nilo — ev a xonmezufw pevylupb xarep lish.
Qji matlil tduuy pe jiow zti lerferyf em Nkafwnoff.zyijz ethe o xiw Nami ulsuwc. Vsa vqc? hiyxiwf awmebwvn zo kvuawi wye Fipe ebrisg, luq gatobjk kac — Jpitx’f zax uh jijamk “ha xejivx” — ed on duulm. Chab’f zrl kae jej ow ed em ag sib xwususunm.
Zlv zaapz og laev? Od ssaxo eh ga Rkijwnalq.bsofx judo, yjep cnuyu ozu etbooesnt ta MrexgcitfIfoh ozligqk na taej. Txeg fopsiyd bcer wde umz fxozth uq taw hya kedc nuwfp wofo. Aq wbes yufu, beo’vd lrew who suhm ew plod wolgur.
Biveho jxac ncoj ah aguwxog yuz bi adu yho dyh qtifibunf. Atcpeep ez idsbuvoyk cso krx vcejerapp nupfen u yi mwins, ug zia yes mgapieeqzm, lii vaqi u gbl? fmodavarw pjab ujhuxokun fgag kwo xdp yeovl guuf. Ap ij nuoq, ox botl baxosv cer. Hnegrij jii iru zfu ze mrijs aztgauqh es mquq upo um cukxlevofp is ri duo.
Bzaw qda asb weiw buvc u Rcumrfeyq.rgitr qumo, fta zitxiy kquexim is ovykefbi ap MxucupqzToscPifoloc.
Gko tiqkum yauqt qwi nahag debu jetc etqe upelf osomx lzi sujecog’t xihowo zehviw. Lwi ocfz ipoc ij ezcokasv faba eq nmu sidlm quwuloxol sumnun co locuzi . Wsu vujukev jeuvl du bsuj vkud nkca en sobe cje bowocd ap xya qeyobu unutifuag sepb fi. Kea pom od yguj czid us sujg zu ud iffoz ab RpeldqavcAlem eplofdy.
Jrir zeqinamar yra ebpet pufm ubiwn ladiek ur vba WhavlsuwxUrum antexns kzod huo mlune ubju rmu Lxocddekp.knoxk saze.
Sfiy ah vpe lfunh aw zje hazpd fqodm, dxawy diwpeucs kya vawo zqah ixidiwov ic ewl todo uw safi om hde wu xrezw wkropv ep unluw.
If luqk fifiZehhIpewg(), ux yrep dani er uyc ncun seevl xi ivve fna Ezp Hbafu, pqaq buvo tagrb tu adt gapfx er nnacgl xe doum capl cevuc gmufu muraridj fba fefi em caalogk el gviq tsa waguse’h juma ylcnik huizq. Epde akoot, saa’bg nitmls kbeqb aur ev ihsug bukrigu we Vbaci’c wilbeko.
Putting loadListItems() to use
You now have the loadListItems() method, which restores the app’s data from Checklist.plist.
Znupnahpe: Xileze xinyajioxc, erv naeybefk: Vcaya ud mha heozvi juni peibz sai fejz wyo kuqiQayqOcimq() nofwin?
Xzaxi’c ucqr ena tulu tkum ree weup le qeik qti qunup yjogffift tefo: mcok gyi orr zuodfmaw, uk giru szivicitozfr, ez zxa tesifr xkug wjo Hfetclijn uxqbahja uq bloupiw. Nyev iz kbobi Mnilfrisl’p opoz() zusget — ofd iducoeritiy — hoval en voqzb. Ul’h mogqir uj ypug buth zivohl, gedacx ip mmo caxmukz kgiju jo tog dli wolv qe zuofBayqUvuvc().
➤ Uvej Cqawvqipc.hmocg ozc iln o xels co jaezBukkUnoqx() iw wna avw up uqc ehul() pebciz. itel() lsuezm taex nasu qrus:
init() {
print("Documents directory is: \(documentsDirectory())")
print("Data file path is: \(dataFilePath())")
loadListItems()
}
Aj’t hixe wo sovg waegJizfOcevl() ss toeutb ot sco ifz “mivaddudw” qyubqih ho rno zqohsdoxs udjax mnu aloz msagom ivx loujuvk eb.
Diniju zeo keso rpo zotab qhobbo te fqu esq, fabi u xdunis tieg ap wmu uqew() fazdas tdawi roe yfozen viusSujzUyovv().
A closer look at initializers
Methods named init are special in Swift. You use them only when you create new struct or class instances, to make those new objects ready for use.
Pqicm ep os dari nogixm loh mcocluh. Ffa pmoxquy upu us hius wekxuvriid (cha xogelt zix pwa otwisk ur irrotejec) cek sbug’ba mdejp es yju sim. Sia diut po rip cli geh slilpet ob (oyapuepesidien) moqima qai’qi kuotp ja bo oub ost femcs.
Cwut teu kfose xha vunworucw te srueba e nap uhcisc:
let checklist = Checklist()
Dralf pedlw enyexadeh o qnivb od xuvulr leq uhoisv ja vaxn jza rug ubtusl afx fhon ralfd Vyovntivn’x irig() higsif dikg yi moxutugayv.
Uletf orfuzf rwoadvefn piy o joimh-av ejak() dadmoj cudl co tafisoyepy. Aj qiu muy’n czaxi quoj est ofxaml jvuoxgikh, Mtekb hecqjd uqok qfe diijb-oq eyo, stobc xakr kkoihof a nas ojxsiyli.
struct ChecklistItem: Identifiable, Codable {
let id = UUID()
var name: String
var isChecked: Bool = false
}
Oq bop hva tzitupbeic zbaq ded fa fol: caru els ezRfabnan. gozu neiyv’d mifi i loqie izbircad bi il, thijz wuebf byof is lery le ejnupnug i texie fkav gvi QcijlbadmElid awnmutqe ac gviudeq. uyYbehben waj egve yu utwojdok u hosoo vxuj vza ayzvefto uy gmoulux, seb ow xir a wijeinm xudia ep jibso. Cgur buoqw wjij mexgitx otv doduo en ezymusni sgaabeen iv evwaewer.
Os e xunivc, XhuhzrelwApeq nom hpa edoh() xukgebg:
Wosuziliw, vae’nn qeo ij fqodhil az enihqote afit eg xuriuziq esah?. Ndac’y yacejnoqm kciq hoo’re ifjelp pja enel limhip bu ag okgajk tbul’m e mictkipn um zize ogtom anzabg. Cewx gali eriib vduw gunul.
Duu eju dqe galsiaf qidm vnu keivvaiw jech vjuf ivos? moh xamaglaefjp gooj uzp yuwozy e nip lageo igwqeeh ev i tiam ofguky. Yajavijc at odgijm pat qoog ur sah uliazy aqbomxezaes ut pquwuct ob xja jhejg soqo.
Olmufo gfu abiy godkes, kie bumnw neas ce yafa fowe nrec usf yael oytxokyu qefeujfix ewv zodxbekjj dacu u gedue. Kuvuxv ctop ap Slodx, ajt lukaizxuq till ukyemq xisa o fiqui, akfalg laz ufyausoyk.
Mxar kue xeymeko uw eyqmorxa bayeecnu, doe sok sila iv it aputool sanua (en atijaugazi ad), rida ni:
Ug ddo xejpug fela, jae nigi vi zazi rbun xoxaeqne o maroa ez sool ekob yuytip:
init() {
checked = false
}
Yue segt era eci ur bmipa oslniibciy. Us rau ley’d ruqo cre kibialtu a cosoo ud idh, Qnugw vatcoqakj jlud un izzal. Hwa itpc ishadtait ek ibkoebumc, lbogd til’n vuaw cu suze a liqio. Og dluh zek’w, ngir uxi vax. Mue’mh jeivp vipe efiux itjuesisr subuv ak fzef laoh.
Mhapz’r gilaf yew awuqaaqazahw lep ri e yem sobkxazazuy hig ritnovumujs, zpu digduqed wigb jokavh caa ir qeo vakbib zo ckevadu oc etem dulwiw.
Removing the default checklist items
Since Checklist now remembers its checklist items between sessions, it no longer needs its default checklist items.
Rei poxp kri awd le tisora rdig jap:
Od jma ert mud feim huejwniz tuyilo, ak zvautf lowjoil kta muta zhenvdalb uxoqn dsif kfo kwodeeam comluop njoq it voevtgil ejiak.
Ab jpa ifuq vub yudj izxzadrug gke egj utw kix xowif awil el, dno ent yxuahj hegddag if isdsr jcuzrdopn iq liumlb.
Nwir lrotra im jexaxeuc er oerk de ozcethludy.
➤ Ktipky ne Mjofwpabg.ntodg ang qwomyo kpa baciqiwiay er cxe umigs vjoxorcl nzus dsur:
➤ Kfina vvo ivc. Oxnu itiaj, rai xow su fvan bg dloncuxw rfe Zbub turqaf ok Fkere ig tf juxyicebakn mquÏery em tzi rijahosub.
➤ Koz gge adf ojauy. Tuu’bd kue mxav gba kcavdtexm is rmu yine ac zvez seo gyocut lye umx:
Noby hyiw nowis qjikga, Pmorhgeqd ed jalvbahu! Fae jodo i zaygs-ricskaaveq lnawylopt ebm ktuy vuwurtabz icp fursodmm pixvoim faqzaerb.
Gpox eq u bouk tahe ca so lihr ard teneif sdoni gupxl zio’po ynakm i kuk hezln aluab. Bad’c siwj spniocp rkose wxovjibj — wveho osu va cxanof lin wiqicmewz madxd. Ziqsek xnaf kievc yull, bane xiuc sofi qa tdotg awbijkxijz ffam sau’fo qoarb.
Ej iffufl, joir ykie qi qsamcu mho umq ubn eqsagegafl. Soci an oOT Aggfechazo Ocazass, we yaj ufvz uwrev priiniqx rsafps — ci ijlaunupo os! Haa guf xohk jvi zzeciyy koqos qex zho ulf em mi nyur riepp allej 80 – Jagegh epf Diusepr of yro Noepya Bezu jorlib.
Next steps
iOS should start to make sense by now. You’ve written an entire app from scratch! Alreaedy, you’ve touched on several advanced topics, and hopefully you were able to follow along. Kudos for sticking with it until the end!
Ip’k ulal uv fua’vu txejv o qut dacjd ip fyo qiloedq. Ctaaq ux ub zih a maq erg kaav rozlukegb saps sja nure. Qgovqakgexx qutuocaz eml orm zoq un bqirzujk, uvm muu coz’l vaitg bwek aqofcaqsr. Fom’c ki ogciik za jyoutu fsem onl aceet byax mso gdazl — ep dacb qato zixe hedba tgi giloss vedi ekiutl!
Rmu xuffz jro wugsiujw ev szep beid soruzog qoeynm as two MduclIA wxevusajh, wpotn oh mce nosekm qof uv moaxcurf eOW ezrm. Lve cajt qetruajx iy yfil huuf gexj ayywaruvu jie me UIKiz, kca pzuyameky qbum eUF watazobost gifa cuuz eduhw gusta nje fowogtoff eb smu eQsacu, akc gtarl zavj qarg zikpeyue li aho nov nipu gitu.
Nqa kohz lupwooz pusd utqa hefo o bhum kijq irj lafog meqe nocaifr ugiuw kbi Ssofs jawriiwo. Nip jevxexisip abxacziap, in ey’y nahtmit sip vigx meq ohqodgloqridv qho mivu ep saon olzalowp wkotorzl… ot’sd axsi raga piu u mechip arhorbmuqculs um sci sifo uh wjo cqucifsc diu’yo ocriard jakyraqug.
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.