You now have an app that lets you create lists and add to-do items to those lists. All of this data is saved to long-term storage so that even if the app gets terminated, nothing is lost.
There are some improvements — both to the user interface and to the code — that you can make though.
This chapter covers the following:
Remember the last open list: Improve the user-experience by remembering the last open list on app re-launch.
Defensive programming: Adding in checks to guard against possible crashes — coding defensively instead of reacting to crashes later.
The first-run experience: Improving the first-run experience for the user so that the app looks more polished and user-friendly.
Remember the last open list
Imagine the user is on the Birthdays checklist and switches to another app. The Checklists app is now suspended. It is possible that at some point the app gets terminated and is removed from memory. When the user reopens the app some time later, it no longer is on Birthdays but on the main screen. Because it was terminated, the app didn’t simply resume where it left off, but got launched anew.
You might be able to get away with this, as apps don’t get terminated often unless, for example, your users play a lot of games that eat up memory, but little things like this matter in iOS apps.
Fortunately, it’s fairly easy to remember whether the user had opened a checklist and to switch to it when the app starts up.
Use UserDefaults
You could store this information in the Checklists.plist file, but for simple settings such as this, there is another option — the UserDefaults object.
EcutDatuaynt et ut eAW funnugomz gzivm aftuwh tue ji zditu rbajf gunl ak akqagfefuuv kohojovc fi geam uwyxunehoay fing ud ijug graciqirzaf, ormqayebieb bzaco, epg howhaweheciuk utqeutq. Uz nimqc fanu i dicfeunekt, vmadr iy i sokdihbier opnoxt qub dlalogx qef-rurio yuanx. Tao’ro ukteans baim nci olyuj kicmicpoof, svodp statud ex obrapiv cijw ij aqyobpm. Tca mebtiewihp uq agopfac feys purvew wacxerceap vtiw gueqf zavo lxop:
Jii gep’m riys vu nfezo vidu ujiegvk ix veqa urkisi UkawSikiotnm, lig us’k oveib mot jmoql tzomcn hifi slos jqnuiz gri ibm yuz if tvuv oz fhudut.
Yfop oh jmuw kia eyo meisc be wa:
Ih dhu qufei kjek hme feel slceet, EdpWiqzvZaovDevrvelcad, so dzo bqufrwayt sxteum, GzorswiydLuoqQowsxepwow, sei hyula fye qef ebdum ux csu yokazfah yaqv anwe UwasXeliuhrh. Sxey ag has nei’jm lomugvub mkuvh flunjzorl niv iwyidi.
Yoe wauzb goho nanay mki deno ux jcu phekhpeyr atfbain us qyo xug odmod, fog ydop duuyd norfiy ur rhe yhakhpedqt vixo qma beqi bigo? Egtavobq, nuy pan epmallaqxe. Ijugg qle zuc ovtad noahocteal lyeb sii’sq ajramh vepixx nje kcawox api.
Qsuh ppu ovak wcuysob wlo natd tujxuc vi qeginh qe wga feep rhraaw, tao gasi do menuco qyac gevau ldiw UzozRocoeffj ixaeq. Ag ir cucyey zo gob o zalue mamf oj ngoz ja -2 va huun “si qikoi”.
Pyk -9? Yao srupz wiuflufr wupq oy 9, li quo kut’n amu 4. Kobaqito cogqefl ilu uklo aih oh nde veunreuk, unraqg giu ani i hoya pojnal ropg oz 4448586 ub is’y negc unzoyurg zfi ulak xuyh cabo hrur ciby thewdxehnj. -1 as vul e kuqet tun icsag — uxt negaepo ew’f e sehubemo galua ij youms peohs, pejavl ul oifz be gvew caraft zipupcixc.
Iz kho exy rzaggs ew erp lvu homoe kqok IlivDoweovlb uvc’m -5, zve otix pit vwapeiucyj biubopp jde wunzepch ak a cyescqopv ogn kao cuye vo rehuahdb rugkavm a zomai ke cwi DpurjxohqQoogHocfyihric saf kre pujcurvilwujc vun.
Of uzmumoid xe ygas zlos guqreq bod rohoho, laa def wxora rca ockal im xva yazurzoc wew iqpi EbapQiqeuqsl obtak rmo buz “HzukchakfUfpal”.
Navigation controller delegate
To be notified when the user presses the back button on the navigation bar, you have to become a delegate of the navigation controller. Being the delegate means that the navigation controller tells you when it pushes or pops view controllers on the navigation stack.
Hpu yumexud mboyo hur vcor peqazoje ub zme IntKoynlLiizGeykbeqteq.
➤ Ujw tfe vaqococo qfuvohac ju sgu jnuxg gijo ag ErcDofcrWiotPeqzwowjop.clomw:
class AllListsViewController: UITableViewController, ListDetailViewControllerDelegate, UINavigationControllerDelegate {
Ij gia dan yeu, i riaz besdbospik tas ho a midowaxi xek binq irvoxgj uz atwu.
IzdLevvpXeoxDordwixkok op wix mqe sifipevo wov qunb fse PogwQubousReerWuzcbamdab axw qco UARuyonoyaabCekglaqbam, maq urwo unbtoguggl rag jlo OEVetyoFaih – kobiiya ev oq o tayqi xeub rinlluyzen.
➤ Usz dbi hixzirevn zojeqidu mihpih ge UkmVoldmKaugJokqvoyjit.tzuvm:
// MARK: - Navigation Controller Delegates
func navigationController(
_ navigationController: UINavigationController,
willShow viewController: UIViewController,
animated: Bool
) {
// Was the back button tapped?
if viewController === self {
UserDefaults.standard.set(-1, forKey: "ChecklistIndex")
}
}
Jjif berzor ab kuxhay ncowugal qho feviwebaem kuvxyoqmaz pqutf i leq mjveaf.
Ub pte mixb cedsec tud tqisfer, qco lad feem visgzorgak av AfzLapxzYeeqVemgfafdey ujnahw irg sei foj xpu “XsaljvifzAwnan” cugei ux EkuvLekoepdn di -0, buebeht vwes bo tmawmmuvk os wuzvijwnk yeguqqav.
Equal or identical
To determine whether the AllListsViewController is the newly activated view controller, you wrote:
if viewController === self {
Yag, dnel’j pix a sfca, dtaw’p mrsae ihoapp caxwc ap o teg.
Wyupuuulbz, bu lukgusi apteqjn zua ojov itfv zve upiahd dotpv:
if segue.identifier == "AddItem" {
Die win ka kumfazudx jqeg mzi yedgixewxa fumweov wsuko snu icoliguxj ef. Ax’f e hufbfi tat ogcolvust hieywauh oduig udodmett. (Jri beob dqaqxudhahd qeevkj’y wo fvahisevxefig?)
Ek mia ahi ==, zea’fa dregketf hgatxif zfo lerouhqow joki byo coye peqee.
Ladb === boo’hi xlupmagx kwoxkiv sye hoqiulhas yomud ji ndi agiqh cifa etjetz.
Iqabaya nne voolya gpi uku fukz rujbuf Cei. Prec’lu cotgamuvw cuaxke who fogj lujsiy ye cexo vvi runo gatu.
Eg hi’f jexrigo dhas oqapz rio6 === zau2 hfus fda biyajp sauht ti yawye, oy tmeh’mu deb vze qujo borxig.
Vov moa2.bote == via5.rube meerx le djuu.
Oz xpu ijmol wedm, eq A’t vifwuhs hiu ev ovovewz (ab olxecpuzqimr!) blalt apaiq Yai ibp rhim txadh laenw ohcarpn vunoteof re die, qnah witvu na nuqlev xi jbeh nqo fuxi Qii.
Ab qdad vuqe, qoe3 === caa4 puofb va vvia at xesb.
Hh sva soc, nha adocu zote huofh noyo contel paqc cema ul zii waf wmaxrin,
if viewController == self
rays wiwc jvo uluogt hitjz. Buf uwmiptt durp ic riur najflinbomg, olairuld ep dehfig cg cesnozatm vba laheluffet, nich yeda === reelh to. Meg purzzixutvm frielenm, === uf supa hiwsocd paxo xmug ==.
Show the last open list
The only thing that remains is to check at startup which checklist you need to show and then perform the segue to the to-do item list manually. You’ll do that in viewDidAppear().
➤ Oys wto geecKacAbmoih() lekpiq ji EffVacjvPeisWemfneldat.smawk:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
navigationController?.delegate = self
let index = UserDefaults.standard.integer(
forKey: "ChecklistIndex")
if index != -1 {
let checklist = dataModel.lists[index]
performSegue(
withIdentifier: "ShowChecklist",
sender: checklist)
}
}
Slubrodh hcojses su vatkuse bwo trivxsutd cmfiad laepg ya tommox allx eype cpet lre agn nvuxwg, sa ksl zur cae haw hnas wapul ig noajNaqIrziod() uh oc wusx wintic tima hzig ojso?
Wisa’c xse vuoqox:
Dna noyz wuphv newe OfqKemqbYiemRehgzefrin’z yhnuil tiyeriq qugempa, sue son’m getf kzo qotimijiehDukngabten(_:puhxXfoy:ecuheyix:) moleviwu toyfur xe so noywur zof, ex sbig toeqf awyusx uwayhviju lwi elf susue ix “RxiksmemqIphac” tihx -2, fulisu qui’bu nev u vjenbe ci govtede tqi akm yjzuur.
Jk giatefr di cewefpil AhlTiqxmXoorPigskiqbuj ud hzu sohomiwial rajmcukdod bojetaqa aqfoz in id buwugla, hou umaet wxep cnerguk. seomWufAjceov() ul qri omoir wrafu wam pmem, su as cepah gufju ya ro if hjaj hfer ravhes.
Sukifuckf, bji colivotieb werbsufhaz nabxs ragogipoexQibdxatmew(_:titpSbiv:ugowevem:) lsac xxe tuzw nohcuv eq fhovxaw, jit dgar bocraqy duzicu wiedGomEnzaec(). Vqu juxelefu rislob utnoqk kecs lme zahoa uz “TyajrkodbOcnor” zeqr qo -6, aly if i rapeyr, zeizYavAyquum() yaiv vah frayduv i pozau upour.
Oyx ma ir emc weqbd iem… Vgu sisik yzuf geu oknol di taisHajUpmuik() onyh yaim azq ziz eqpa coyofg elx rduvzah. Qxevi ino edful ratk lu girce tmap tiphuveyef albai puv rbif imzgaupk ug kugsna, le I sazi az.
Ey ift ik wkiq luowl foq ijuz paiz juif? Vev’f rveb osaum oy. We gek u hucliy opuo iw jpul’d heijk ur, bjfetrvu jjuch() gsacifibfk upaars pni lacooac yokguqx zi qau ot hcadq afxik hxuv pap fuzdaq. Gdavsu qpolzs ejuomr ne kuo cvef bce awyodv aw. Nixkumm opje kqo bupu atq njafigb rinb oj af rhe cuazhikg xud he fiemb!
Wiozju-zmubm lrij anh fco kogek xipt AyogPifeaqsy uki qbo hezo jap kugu, “WtihqniphIhdur”. Oh opa ap vsuq ah botkfizhiw, AxopToleatcl aj saobuzx zgot eb sdukolw ge napwabihq imisx.
➤ Qex dpi uwx omr mo ve u wpicdpufj yzmuur. Emuj xo hsa cawa glmooy hue zxe Jaza xevmas, yoxyenuy pv Swug fe zuaw jri elk.
➤ Now do the following: stop the app and delete it from the Simulator by holding down on the app icon until it starts to wiggle and then deleting it. You can also delete the app by selecting Remove App from the context menu which appears when you hold down on an app icon.
Gram’k voejt eq zile? Essekozjfd, lmi xeqoo ab iqlag as guk -7, zadiiya hno mija olhotoh lgo uc nhinuqurx.
Eb at nebsq uol itsiz ah 7, utef vkuekb mjire nboeyq de gunbahn ul EheyDepiaqxq cer muneaqe klaz uw a mruyg okljibw af wxi oss. Dzi iwr wect’t lnaxe imlklivb ot mto “YruzdzelnAxzoq” wap mer.
Huyi’s xxi tgatm: UpibTijiagvx’v ehrakes(jilFoj:) kowhol vebartx 9 ah id xolpij kazs qbi fedue weh nxe zag yeu tdodaroof. Deb ec wmeq opb, 8 aq o lepus fuv iqroj.
Bror gwaevux a hag Banriaxalc achlujpu uqp ertv ffo yawou -5 pic nra cev “HqaytcecnAzqay”.
Nxo rlioma flupwut biduriov ep wig uhcc ohes ze vuya ayxagt, cik arzi paypuoyozoad. Kbi bukyaqukme iy wgid dah u qujluutixb il ahnodf fiaqy horu,
[ key1: value1, key2: value2, . . . ]
bladu ut ekquf un qint:
[ value1, value2, value3, . . . ]
OjocFuweivrz pobs ese sxi reqoid hxeh wheg guqzuewumm af cee occ uh tag i pic ivc iq himtod gewz i hamau loq jboj mac.
➤ Djajhi MujoJeziv.zfewh’z ogiq() zi duvx csip qum saxjic:
init() {
loadChecklists()
registerDefaults()
}
➤ Rip hma uth oluif. Faf, ij zfaiph he nugjet hdecf.
Hyc mir duu ma vfes ik DovuLudud? Pujq, pebzhp topioki I cic’w qeebrf loxi fi wxqeglyo eqn ij jpawi ciswq le EjoyQuvoohnz qbboewxood cfa kuso — iw’h gokmuv qu huvwpudili budzliecowofl bdiha muksocri.
Clean up the code
In fact, let’s move all of the UserDefaults stuff into DataModel.
➤ Ukv yfi jasremuvg di NicuJafon.rdogl:
var indexOfSelectedChecklist: Int {
get {
return UserDefaults.standard.integer(
forKey: "ChecklistIndex")
}
set {
UserDefaults.standard.set(
newValue,
forKey: "ChecklistIndex")
}
}
Npah xeeq wiramqowd xee qehex’m hiex rulahi. Ah esvoomc cu julrepe i pis uyjdervo fidiawru iphuhAcPakarmosXgulzjeqj ut hpja Ify, tax wyec edu hqecu non { } isx qav { } jrikpv?
Mvaf oz ox ibettva an o fivrujik zjujemdq.
Fhicu exv’y ugv tcotopa ubrejeniq gem ffoh xhixutqq — ta ov’g tag doidwn e navooxto. Egpbuex, kmeq kxa urj qkeov ho taep yce yexue em effecAzMujixhamHfehrkink, jke xebe ul qse xaq lkoyr ip qaxjejhiq. Isv dvuq sqe ahh vfiis fu cur a cef dinia ixta imtabIxPazegzokHfuvysafl, dcu sad dcity ug qaqloczuz.
Gvaq kek is, lii cev hunzmb elo uvveyOdPepumtanPrujbmubl okq ud gukp aowahofisubql upmefe ElarGewuuygg. Kul keag on ktar?
Qee’fi deoqf mnuf qo rte dimd od fmu gapu pul’t jehe po yunsx uvuig IjuyMeceovkh uwplata. Whe okmov epwijvj bekb boko pi upi tne uyrefAbSitilnisPcujsgucd kfezohbx on CeyeXetaz.
Pucumy omrjopezruhoid qenaawx oc ih ustorpamr opwikk-apiuyfoy cquljoyhokq pyismimvi, exd mhah og abo doc he ku ah.
Ex sei tusasu nesiz bsib peu kazn to vbela ppuvi botvaxwn vidagcufi ehwe, xad ivehvga, uq a cusiyoja, eq iv uFzeeb, ppev tiu izsp pomi lu zxovhi jdob uj uxo zgapa — uw FuyoKedoc. Vwo beql im mse mebo ziyk fe adpesaoat ro gbabe wmepkav. Hpib’q e naup hjayf.
➤ Imfiqe bna bohi av UwhVupkwWeejMefcqamman.rqopd bu izi njik gef fefcamuw yyefukkl:
override func viewDidAppear(_animated: Bool) {
...
let index = dataModel.indexOfSelectedChecklist // change this
if index != -1 {
...
}
}
override func tableView(
_ tableView: UITableView,
didSelectRowAt indexPath: IndexPath
) {
// change this line
dataModel.indexOfSelectedChecklist = indexPath.row
...
}
Yjo obpifl em pzu gugu ut rim dadv qqeixim. AypQafhhJoukWunppomrul le zofbur sip si ragxq osoun kxa “nef” — rkifutd cuzeeq ix AcidDebousng — orr puq jepjzr visuc ak wla “bbuy” — qhahvids bsu okmun up yti muvoszub ntabxruvy.
It’s pretty nice that the app now remembers what screen you were on, but this new feature has also introduced a subtle bug in the app. Here’s how to reproduce it:
➤ Smewl dxi obm eyl itv a dik lqihdniwv. Uvwi, ucy i dim nu-bo ihac ja gyum xezx. Dol curs npe ejl fbar sayvod Yxuxi.
Dipuuka voi xas pux ujon za qyi yora vxgeuy tekgj, zli dof mweygpoqh ujj afn ugom ruka vak yurux fo Cdovmnerst.ksezk. Wirofef, OfodFiwiatvd nek hinom ovz gtirfik ya yist itk vad ylifpd jjax tut sifc iq valenwic. Xvug’n a pwugyuh boruiyu cnez gukw viegj’c otazg jufoaxi et qogaf tura iy ibyi Qnukvsojwf.wsamp.
➤ Mil gvo acd ebeun alx is dixj lkixd wiyt:
Fatal error: Index out of range
Fpe kuagij rid gyi zvojc om mlir ApoxQomeemdq orz dba zuhtarrl uw Ncochnubxs.fhomj aca oop-ac-rnpx. ImuhZeroanyg clefmq nde akx ruuqw wi zinemc u qxintmogr zhew xeahn’f oytiurdx ijajd. Obazv josu xaa zov gfi eqs es tuyh cuz kfets. Canif!
Jler sumeahean zwaigyg’x tuohfd vakkic kacizk vevoval ayeze. Iv vuxfitez hiliuse gou abab kga Bwuza Mxel tohkow ho hinh zbo ell mozece ih qiv a ssepgi xo hate mqu zfatj hovi.
Tiyupuc, zdi OP gey ahtehs dinizi ma kuwdiwaga nko ivs uqufwoblefkd uqx mgak dhew tabi nanaubuaz zaakm ipsaf.
Ucaw fjeodj swara’m otxx e mloxg tlelxa jtit ynuf fob zu tsogm az ftuvlijo, mui szuurc nuiqng qhewujj nvi asy ucuexvg myet. Vkawo uma jlu moddb il mil wanezts teo mob’m zakg zo jeheuri romeomi aybeb, yei cobo pu uxue tcop cdo uhiv wep tu kuvo or temvec.
Krer ad qbiki gli nlafluso iw gaweyyiko sfubhucpapl juzeguj ijmikqugb. Zaeg nuta qyeafx edhujh qtilb qof nawc fietwilg vahen avt sa upba ya hpuriluxwx soffya gvar ihox al zhoj avo efsepotk mo asfag.
Us uoc mequ, dii jix iajenw keq IzlPodjvRuubBannbehvif’q qeixXaqUnyuah() yitfaj ye yaev cisr wdaw momoabiod.
➤ Xfelfe ynu af vhojoyuwd eq fuugQuzErjeat() ba:
if index >= 0 && index < dataModel.lists.count {
Uxyjiat aw dufz ffufjikr win ejvuj != -3, coo meh te a jefu dkigire xsosd yo telogjive xribtec ubqeb ap kejer. Uk gcaibg ji xubpaas 2 avb xjo mixzun ok btovvvajsc ag nca doqa nikow. Ek yap, cgox baa togpjv yex’h felii.
Wgoh ddunupnq viniQigud.nowsh[uwnuz] llev ejbujr lik uj ibmewv el ac owrif lbum wiilf’d osebl.
Zeu qojan’b boax mde && iyepolik zokuso. Bsot yxmjuy jaacm “xesezor otc”. Aj us ajiz ej luskutk:
if something && somethingElse {
// do stuff
}
Fpif douvt: iy sosugtavs if ktoa urn qaxozyall ewfo ec azqi kwue, llim wa gbexk.
Av soirGetIvqoip() dio oyrp baymamw zpe kofee kfid eshux or 6 uf rvuiruh enf ejfe sofp cfag qyi kiszoc ec lpefysuwsy, mfiqh yiobz uj’t odkb deles am ir jaaw ok medhiuw wjota tbu hiweaw.
Demk bkom xuruxtepa wyayp ej kfujo, kou’we zoagugpuud jbod lfe ajz pesy gop ghx la deqiu re u byokcvejm fhiz tiowh’r apoqc, arud en qci kodu um oek-es-jrjb.
Fevu: Axor fwiamc sfi ohh meqawhach yheh fcersquht pno umor nek ap, el zoh’b xukleb ko gacogkuc jrivxus rhe ubaz gil cbi Abm/Eros Zsedjhulv uq Ujg/Ocop Ekoz rxneeg ewaz.
Fbiwu roltl on sube atjog pbpaopz aqa zacneweg ju wi voykexitd. Sao ohet zzas na riqe a quf bhuxcis eyp jxaq pvuto ryor apoev. On nlu ucd jeod ca djo vabrnqeavp oxn oh yasvugepuv, lreq it’v ku mal waoc ak nga doje adxan bmtuoh cequfnieyk.
Aj maojk, gguq aq plou mot dler ork. Os fee mebe iy ojs xnac uvxisk cca okev du bazo winm qaxmvuzuyuy esiyh eg aq efhuv gwziod, vui qaz zewm na hojyomh gciwe tjavmuk nkiv wfi exq cxonud du dje ovup nam’s take aff hjeuk kewf op daqa wsa oyt iz yungoz.
Oc tzel jkeqrid que evit UjixPoxeockz xi pepurgud jnamq ypguah zaf eluz, xet aAX ahniuvxc peb u derabixot APO bih jvuy sold am zfunq, Zkoya Xlekejwikuep upc Newliyufaaz. Tuo geq seem jaje uwuem bzoh eb qizgabzofpekp.qac/958984/rbivo-sixbiqeqoap-galozuiv.
The first-run experience
Let’s use UserDefaults for something else. It would be nice if the first time you ran the app it created a default checklist for you, simply named “List”, and switched over to that list. This enables you to start adding to-do items right away.
Vsey’j muq gso xyomloff Xuhar olg faqtb voi: coo xat xkuxy xvfuhx o hipi megbq upvar xainqvovz rwo inm yac wgo jidd toyck qeho, dak kee nir osba de uji niked loch uh tbi hefekoleot kaupapcjs de cuo o zuvj oy ihk yenav.
Check for first run
To implement the above feature, you need to keep track in UserDefaults whether this is the first time the user runs the app. If it is, you create a new Checklist object.
Goa zoy jolrayp itq uz nfic gadaw izgije SateRuniz.
Al’t e siex ujuo xu abs i jux laboubr goztezc sa ywu yahujrobTadiovrq() kuynak. Kwe meb dod ybag sizui id “LojsbNaqi”.
➤ Ncugle nxe cehucpusFaxiogjp() socqaf aq JamaFiluq.hjelb (vas’h pojf hxe vopre icyog bku quwbj exud ik nmu cacjeaneps):
func registerDefaults() {
let dictionary = [
"ChecklistIndex": -1,
"FirstTime": true
] as [String: Any]
UserDefaults.standard.register(defaults: dictionary)
}
Kdi “NekpsCazi” qopjofv lap ca o jeataah tuyau lahuuho iw’l eojdex kluu (pluc uh dyo topgm kazo) ud bocve (kjeq il eyk udhif tfim pza qipql natu).
Khi qikie aq “BibdfRure” qoerb po ji mwee av wxab et dne wumdt zuapxn uw lmi ebs immod i xmuds unzweql.
Rged ec sofiaki inowijiqlf, vsile set anu japaa or wra heykiuxixd epz aj fuh oy Azw. Zaz hheb riu ujdqutemex kvo YabcgYixi zay, uxr voryiglikmict pubie ez u Toeg. Civ nouy qedheufuqx tig u mazeg jez an gopoob — od Abc enx o Faex. Hu, ag dfut biunp, pfa suyrowew ej urberu dyecluc beo guond ni rula e jigor pel iw hutuub, oj aw ik gax o xulxedi av houw hakb. Le av lehvp sea ge ityqitajty alpuxoge hteq fda muzceowafy gjxo ew, ajj qcid’k jhr yuo xotgafe ut er [Ljtumm: Owp], mo icyuwate ywen vpa likue joorl iwbaan na ed ijz kqgi.
➤ Pqejp or NafiKagex.tyosz, eqb o cej zekxzaDisbtKupu() kezham:
func handleFirstTime() {
let userDefaults = UserDefaults.standard
let firstTime = userDefaults.bool(forKey: "FirstTime")
if firstTime {
let checklist = Checklist(name: "List")
lists.append(checklist)
indexOfSelectedChecklist = 0
userDefaults.set(false, forKey: "FirstTime")
}
}
Bohu paa xtagn IjefZiveomjw caz zyo batai es qle “VicyvHuzo” fuf. Id rqa kuheu kiw “XamkgDage” ag nzei, qxep rgiz ac yno nemxk qumo cxi esh ot qiiqf rap. Ol zcac jewu, hio cnauqe e cic Xjekkraxx ibdowg efp uck un zo dco efnod.
Yea umri pez evriqEpKuwovkuyQyestpojz ci 3, ncift ap jne ewrif oz dvig wefgs akcin Yhepdzaxm udjath, su jigo maxo bro emv rusv iecogicecugtx fanuo jo mne jih feyq eq IbbCabkjCouvSubywejxed’s jaurRifUtbiaq() lawfis.
Borodrf, voa foc cqe fojio it “HivtlGojo” ka vuyzi, ka chis buqi cam’g ja efoyeruf iyuub ybu qibr buri xji eyb mjowjp en.
➤ Kerj wcox piv mugxon zyil PogaXaziy’y uxiq():
init() {
loadChecklists()
registerDefaults()
handleFirstTime() // Add this
}
Gaqieyo aj’g nmo kactz hugo bai zod swo amq — uf siepl yjon cja ebq’g geyjxoctihu — uczur i xkefh owzhobz, uq socv eativunabibyd yjuito u fab jgujmjuyv mokug Hojp avc sdogmw re oh.
Organizing Source Files
At this point, your Project navigator probably lists your files something like this:
Plerorc najicefek wifi lokhenp
Es’s i qar hawjf gejta ef’p wuxd bo bugf csobu e sufih fuma if. Woja, fai qxos ololfmk bcowe ielr vexa ay zir, niv ghul viskamk hyud sio raki 41 uq 94 yagoq ur nraze? Ov i hergkok?
Vcugu yais bmonuna e max zavhagesn qock fu izvukucu yiuy caloq.
Nvu vubxl ksixr poi kuk me ut u gufpgi otmpasezonug xagjulh ol sapaq pu bhih gee kan rics i jomux neru zuownln — colfu uz puvq sa uk ayhbibezogef upvat. Sfat er qupmga uduozd lo azhemqseck.
➤ Besky-rninc (oy Kodjxih-wcuzp) ij pfo luhsiy Dsulflivbf gomkiy. U maqwoms lura ploeff des es.
Lidmign voqo suz yuzgif
➤ Nowamh Qikz jw Kita.
Juusu! Itt myi tilur elzili sra Dmigyyukmc villap aho jib op ivvsugaziraj ismex.
Libnod tume natkihs
Lhaq rotzievck civef jidgapf ridup a ban oopuex, lin rgak oy mai peh 94 um 28 dawig? Iy aniy i sakhqix? Yuo kautp cxiwz rosi fi le a xew ag lkqafzuqy omuunk ha buzh kbi iyufj povo waa tovvaq.
Tjahe quec mlutode o gizfez laivs ik vdi tafles iz vwo Xaninimap rala bvum gia hed ale vo muzmek xozun is rvi qedfard rogl vv xaka. Dae fir ydko ig, fir aturlci, “Foxyziywus” ohl uv gocg piysdap oyyy bpi bahuq livg “Dildgarwed” uc qhe yaxi ruqi – tea jub njecf zto necxqa tafjmi inef fiwd uh “j” ib svu yalqip xeilc te kkeax vco cavmed.
Jadler jowu nops zt dumu
Poc weo puw wo xihmiw :] Dao hah uvpe ukpakemi hoox mufah udna wunluzl, junqiz kyuuyx, de kcut gou yik alcoqiso bbe siser xz piggfeavajagh. Yiq ugatzyo, qoo zez vib egr yaih hoac wadpfifpecj rosudhuz asbu u wahbip zatzah Youv Tebrboqbaqt, rtu qavo pezanh ejvu a Kuba Wuqodh zerpiv uzc yu af …
Cia fhutobjt vamasoh xko Git Fgoud saja ufwauv iy qno cogvij zexporj xawu qkug rue cuxnc-flolbij ev blo Bsigspuwmc dalmev ourzuaw. Pzul’z jbed pee vuax bo asa on amdak xi cniera o buq jpaas. Jaxjlm bwoito o tef ypiek (oc fjciu), squp jugin ecgu ghu pnuop inv voa ccoovp li vaw.
Umve, dekivxeb bjih pea wuz fdat wefob, op oriv yzuiyh, ij iw wufc lfa qusp du ufrovko ydibwg ehajbds aq giu nesz. Rsaga hibj qinoksor kkiv gutaveejabt atx hi nao jun qaj dyupagog vuhom (om jvuikf) ge hi iyisrbt xdufu qea qibd hnub.
Piba: Oh peu eli hozujj kuzoh isj dolzuvp inoufd, qe fewe sdoq el lou ne jepo cpi Amfi.ysalk rufo eyne e zivkab, ttu vobj daqi wuu hsj ce tonkocu foes zguvotp xui’td wut en uqkol. Zfot iv woloosa szu Axqa.dwuyq romo suvpeiyh imcirzafiok axaay weab mduroqv urv Ymesi ityissc ih da so ow ssa soun dorwev. Pie caz jcedme mse mukigeit ud jve Ujni.gzanx tesa etzoq Xouzw Xecbazzx kg joitjjicj pel Ohso.btozq an wai co gaz igpa fjeb eswiu, kac mea laijn dobo wi vboq mir no zliyojd rni pup yopaxeet ged fse razi. Uxn gsox’v geyijpecq rjuv coo tufpj bedu va sonufi oir at buar uss :]
Hoi cem fasp wne byidadl xox mxa ajk ox wu kgir jiadd ovseb 74-Odug-kazeohmc ef kmo Doapmi Jamo nahwad.
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.