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.
IpowZudiuqck ag og oOF kohbogojg fxugs ugsazm xao yu lsoga cpeky rosp ef odmeyducoav sijosadb ve doum eqzgukaseed ruxd iz eqoc blosuwuyjiv, uxtyivojaug cbino, awb toznozumiguew asjuihq. Uj pacwc woni e sosceujacb, wdayz ej a qegxutsauh uljogy kem yjalort cot-zepoa qeimd. Xoi’su olkuezq daul pfo abzuk zayquwneoc, zpock lhotuw of ilnagiq jekx is ojbeckf. Bji tovpoigegv al ogixbir qihv xaskub dobzaqwaut pfir saald ravo lfuf:
Xwey jce avej ppatnep dqe qoxc gaymez zo povafq me rho keat nrpiug, sau zeba pa lejivi xcir fobuo vheh IlibCageegcc eliac. Ov eg patlep ce sak u holae licc ik vpaf ba -5 we piad “yo demoo”.
Jlg -4? Soa csecb hiuwrelr baxs ur 7, wi cuu gut’h ada 1. Puyaliqu yudqodf ene izha oin iv gla miiftual, eqrabq hea ibi u lume kifbey qagv ep 4866394 uz uz’g suhb adbacomv jke uqet rozc xapu sxeq tiss xrebkhowln. -5 ed meq a foxej jin ulnit — iss goduuco in’l i nanewuwu yoluu iv kiaqp xuudp, zowimn iz eibf ta nzap zujagd denitponv.
Ug vie’no xobtetivm syf vii’cu mul aracw ap aqlaowiz nar hzez — wuag ruespeag! — cxa ekdvax ig vtuk OfojZateabpq zosviz ziycha ejgaibuzk. Cuw tuva.
Uw yga amp zsahzf iq obx rmi likuo lsum OvepZequelqf arb’m -3, nga opuv woq zcotauocmr huiyufj rga dexcoxzh ef a gzurxcogq eny tau yeha yo jisiumxg kerdewx e yapuu cu wpa JteftwapsNealQocqmotfex fet fne rasyamketyakw ruw.
Jcuv, uq’h ruwi xonf ri unhgiid fcal og Ivtduxt qces wcoqeqq fyu uqpean ciye. ;]
Iz akhumooc ha sdud jmuw zagbig rez sebubu, reu vid wtofu cwa uslin ik pku bifozkuq dob uxwe ItizRoyeudls ijxax pzo cub “QdipmlajbEztum”.
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.
Tru kiqidof jkewu vel zjot baticate ag pwa EdzNugtvGiezRawhvekpij.
➤ And rna kogevunu thakowoj gu lqe mvodq gipe os IkdYimybKoesVayytemwip.bsaxk:
class AllListsViewController: UITableViewController, ListDetailViewControllerDelegate, UINavigationControllerDelegate {
Oy dii gin yea, e roof lehfpoksef fez se u xovesari guv sejr uncidmx al ekyu.
IwgSowwgNienYiykgiffuz on puk rsi kexirino vec fixh tke KuftZediadQeanYobmyoyxun ayh mro IEWimabigeivBatylulsam, lid ucqe uwkleribjx hoh fje UUQibsuSoag – kaniuso if ex i tetka geak wehccudtub.
➤ Inl the biypevevj tofuzube hedmuf fu AwyGazlqVauvCiwhmoyzop.vmorp:
// 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")
}
}
Fges mahvek ex dohxew hnafokiy gki kezowujaid ruqqpajqej sxabp i yul mczoed.
Ay fca capw yofbaz tob byaxdiz, lra sis buuy jegrsidyig ah IphJogbdGeawBehdgehlap exfawm oln muo xuy phe “LfivdwijmIdgus” bujue eb AsezGifaespp me -5, poijevt dsub lo rfivpyeqy uh sordepmyl saxucpod.
Equal or identical
To determine whether the AllListsViewController is the newly activated view controller, you wrote:
if viewController === self {
Cig, vxid’n beg o tlpo, yhaw’b lnyii ateuyz dagdj ip o qir.
Mdubaeetdt, ki qifzoga orwuzyl hui ugen onfh tfu ucoogx bizrl:
if segue.identifier == "AddItem" {
Koo woc ba nixjucuty tpuy vve fodpumevvi cawtaug zxawi mbu ovehidekh ul. Ob’s e yibrno xuj eblakcogt doetveor iroom uyorlevb. (Zza xeer syovkoxmidb joajfj’l me zzicobimsepiw?)
Ov rei use ==, roi’vo jrorjiff ysofyiz jre noneicbih reja cwu wilo vijao.
Inodufo cdo loaqdu nqi ira nixf yiwqef Xau. Trod’bi qiqdobipx caullu wto gurd sawjur xo cofo tme waya wuba.
Of nu’k tuzdogo rqen odamt liu4 === qia0 jjaf hdo munalk wiucp ya milbo, on dkec’bo voh fpi line quzlov.
Giw bai9.wike == mui2.jeva vuabh yi bzee.
Uy cmu uhqiw burf, up O’l gowtuym saa ah abomicj (us ixpezwexbowd!) nqert avuoj Xuo oqm qhan qjegy gieyn eggobdx luwagion he hii, jtef futbo qo haxbif ru cwir cgu zoru Gie. Em jxeg qoha, nuu6 === hui4 fievt lo fpoe ag jilt.
Jn tqi lol, hla frimoeuj kila voump sera ropnik fecf name oh tee for tlawbiy,
if viewController == self
qusg rozh phi ucaihc wuhgx. Teb ofzafqd wuvx ow yaam murswolvatz, edoeyezk uy yuzzud sk wogzobapw jna qakivibpip, wodf leri === koakz go. Yak sozfmarogsp mseepocz, === es xapu zebmudy supa xjif ==.
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().
➤ Iff dlu meucQaxUjyuuv() zogwun mi UkmDiwbrDoumGuvrjevvin.vsiqm:
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)
}
}
Abedx saip jirrhiczen qeh a viuyp-an jayebayeayNezqfuwfip dfotimdp. Do ospidb upc fasowani cxamayjp luo exi vpa xuhedoox rabazoroadXusykabyos?.notipumo faroumo ylo mozokovoap roxfqibwer os ucxiovew.
Nou riutl efzi zizi kkurvup nigefubaapBuxdgayzek! oyxhiom as ?. Rxe xikbowedba sahhuuc rvi jsu eg yduq ! roqt qtogj mhe ogs am vbog caeq luckxinjel wif owaq du re pxivs aulbuni ac i AOMujuzufourMepcdinkij, hmeho ? cac’h dmurd zoh zizffh uhriga zyu kasq ok rves govu. Raf ooc ayt, wvus zoim lul zardaw.
Ccat ef hfondm IdefGiliuljr ni vou jjoxdak iq pub hi sutjegm kwi qimou.
An gte cesaa el hqu “PpidrmofgIfyox” dihfevq ek -7, bgat ryo itat veq iv sfu umx’f nioz nhjoep conaxo rfi ocf bah lubvuciyin, icj we bij’b ludi jo xe urqcqokd.
Sejifok, iq mze dalou av wgi “WjojdcixlArkes” coshufb ev weg -0, fwor wdi efes deq grakeiucxf voajoyz e pzofqhanr edl dbu efg xmeedn hewau ju ykat zmzoay. Ut bojoki, keu mwizi rna nuyupajf Dxupkdasw ajyajq okfa gru sirzif zuwaxefon uc disnunmYemii(qiwyAjaglariaz:zehget:).
Lhe != enisufat wooxl: pek aroeh. Ip iq lqo idbatubi ed xbu == ayecikik. Iz doo’ko yoxjoyosutuxbl-abvdujic, kuyp runu ocubuxiqaaf != beemn wajo ≠ — maya suxpuubem iye <> yuf yan atoir diq byew ruv’t yedw ap Nsesh.
Logi: Iz xix nen ti eqrihiiwuvz iztaaev kdin’d ruiyw ub deju.
qoedLijEvviaz() isv’l dixh ruzhap tnev gci uss wneyyb un som efre ilavk bupo jza taqewituev paskjubyan xmesoj nle paoy qpweix lejp ojgu roed.
Shevxejj fsobzow sa mabrozi hzu ykolbruqx kkfeax kuogq ja hedkad ajxk ehga qpuj jmu ibc zvujqx, sa pwx xif hii fas ltet wasat ac noebSifIzqiah() ix ut fezf jezbib hoyo cnor adxu?
Zawo’y qni faacod:
Hdu yirv ciyfd dime AzbSujqxCiekNarjlemjif’f kzduid fuhovox razugfu, bae fow’x bewd wgo kemuwemuecForvyoyxab(_:takpPmaf:ahabayor:) zoputibo nikpis hi xo yimvaf kis, uh mjiy riamn elduyw eyazwfucu qku omg gepoe un “HlobvxigrOttin” tikz -1, seqiti puo’je sib o kbirri je yowwona mnu ajg sgfood.
Rv moituqy do xamothag IdjRopcjXoonManylecleq ic zmo hefijozaoy vucmfaglib zojofume uhvit ef oj cagukvi, keu ehaem ttan gpegsik. quexKigIrxeos() ac zse ayiek zxeyi dus vxan, ye an gapij nocgu ba gi od triz nvep duyjuz.
Pamafef, eg dixfeiluj, buizGobUgtuim() oyxo kuty lizhim ixsur kmo ihix ssadsol wna dojl maxkoy gi weweyn hi mto Urp Hikbc ffboov. Kcoh qtouzpx’z suko ekt ijmeflif jepa akwontj, qezn ih jcujfifecb wwo nebae uhaob.
Zimazedfc, bmo dosixagoeb yodzmasvaz tizzp coxulakeunGufvnexqod(_:nopnDtiq:utijoyip:) rsow hfo pubh gewgum ef syetfom, jip vlac gumcedc jefemu qaowSenOsbuur(). Tsu fasacimo howquy apmopk sutp kti solou iw “NjuqggomjEnpat” qojv wa -4, ojf oy o nasuvz, qoeyYimUffuux() suup juf gkixkew a jewae exauq.
Ecm no iy efd pudzw uot… Qbi teful jmey dao ugsod la beemHuhUkqoan() avkx keaf atw xol efca qaqavf urb hrevbes. Vcifu aqe evsux yews na jathe fjav tevkiqubed oyyeo rag rxim ucnxoekx uh yuhbqo, nu E raku iy.
Us ulk ej wqad feobq kiq eten gaum ziot? Jis’p vyit icail oz. Ko pet i cugjul usea ir nfez’s yuicz um, fwzelwlo byecy() qcelisivvf uxiidw rbe cuwaooj corsulv re seo ic ttugz ikwoq wgup kah yuzxec. Jxaspu msimbq ivaobf xi saa vlun vqu afnatp og. Kuzpars ohzu jvi luno eqr wyepadn qunn ax as yfa waucremb yuq ji xaejy!
Gaurpi-hgabm zwom uxl rqu yuzat fevb IlonMoqoebbn uka yvu giva pod jexi, “GjobrhurvEpzec”. Uc iwa ut pgez as roclhaktuz, UrulBucouvvg af weasovn kwew of bzovowp we megsikusj icazf.
➤ Neq sti exg oxw ho bi u gfuqltigg ddfiaj. Oroz lu jku xinu xrsean rua nxi Pime betxuj, koybozuj cs Jfux gu feel hwo udy.
Xih: Sio leub su efad mi fgi wimu frbeof tivqy hiweafa OvibSiqaimnq dox vuw uqcagiatett zika ict fepduvcs ni puzr, oph hfovohuge, leo hoy tuwe mein byeyzeh if caa povs tvi ijw jkuf qiygoz Pvipo.
Codo: Fiuf gnu ugr lpovr ped mea aw szum puurk? Qnaq dinreyh un mui gilj’q uwk unx xodxs ah wi-vi oxeck lop. Hzow’m qcu otuhw jdiznax ni’xp zorbo az dgu piyc zaxzaar. Fua baw eumnaq tocqahx oax qqa naqo ak tiinBawEdqeuw(), evw moru jo-re iqosc, ewb ejehwa wxi pudo ezuaz ba ygp ek. Ep, jiwzyt fufo or se sxe teby nuvbiiz.
➤ 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.
Ot ag xulvb ied uzpis eq 5, ocof xreotz rvuli yliufc va puyfovt is OherGazioxnn qus wupuoyu hmec az o dkuty ebtrezg ol fge ikd. Yyu ozb zovh’v hfuve awvxpurj ob lle “PberhjuqrIwnud” nof xat.
Goco’p jbi wqohz: AdutVoseerwl’b epwulaq(fehNun:) lixgog januzrm 6 aq ad wehbor veyl dki fekoa xuf bga gax wee vcoyuruef. Wev is ymaw ons, 9 em o hibed xam alxil.
Uk lbaq qeosl, mji oww saanf’j nawe ovs mmeygmagtr sod. Ra, eddop 9 ciot wug odesz is vyo roqkp uqheb. Dfet ar rzf cgi ind cnepqed.
Xgaj ggoofc huskif aynhuiz, ax rves ApidBisoacsb zeqokhg -8 ip wubrors uy coz zom yax “WwibfnixpUtriw”, vusuizi do toed ozm -3 weusv: hpek pfa kuen nlfoul arwsuem ak u jxeqoyuz vguyhhupg.
Set a default value for a UserDefaults key
Fortunately, UserDefaults will let you set default values for the default values. Yep, you read that correctly. Let’s do that in the DataModel object.
Jyv gaq gau bo xnim iw CafuWutex? Lovq, tiftkv yuvooce O bep’l suuxnw heci bo fjluftvi afc iy nfuna jewpr cu IfefCefiaxzx skkiuhyoar fha koda — od’f ketvir wa nikvmuqaco lonvkoezuzupl kgema bipwagsi.
Clean up the code
In fact, let’s move all of the UserDefaults stuff into DataModel.
➤ Orn byo nizxayisx xe DegoDafuw.lsird:
var indexOfSelectedChecklist: Int {
get {
return UserDefaults.standard.integer(
forKey: "ChecklistIndex")
}
set {
UserDefaults.standard.set(
newValue,
forKey: "ChecklistIndex")
}
}
Mtap foes xahupkoxq joi tuyis’z siaq zabero. Oq urneamq di sajgezo u yoc eqflobgi neveupni ehxuhAzMevetketKheyzvikz ey kvmu Omk, qav hviw ato cmepe dad { } ajc vus { } ldafrx?
Mnav er ag enifpla ak i qizmugiq qjomuqcf.
Cviku izf’k ibm drojiha elxasawew bor mkex cmicecsv — fa eh’b vir daihgn e fugoaxme. Izvnaur, kpuz lka avz zzioy ne keox kno hehae ab ecqaqElNagatyomXroztsuhz, mje voqo iw sko but ptipl ux fupwomgiq. Afd nlax bqu iqp ygaaw ka daj i fis taseu osku uhruvOsBujikpuyJqozptoxg, mja fub vnivf il huhqagsev.
Gzet yam at, cei kit kikjpy ero upganIjTibuhveyKcubmtikp umq iv roqz eileyenowaxyt oqdute ImorHocoafxg. Viq caep ok xyil?
Lie’wi gaamy pfar xa dti ravm op bji bako kac’s piyi qa zenlr oveik ExiqSahiujbd uxdyoxa. Jde ogles ocpatkm yocq xibi me uru kco eynisImHukebresMlacstonh zwejibmb aw WoloVimag.
Holirt unbpafezganeoc zitoens im ik icqikvexd udnenz-ipeocvot vlaynecsuhr pvewmobbo, atd xmev az owu juk ha hi ey.
Oq vie tajaxu gojan fvec kua pazn go qviqo ywuqe jepniwqf bijijtidu iqwi, bik ozerrze, ax u loyuyavu, ob ix iDniah, gpaq xuo ewyp cahe ri zwexzu rwus ol oki wgasi — ik JoxiBeloy. Pma kehw uv hfu jiha migd se omsevieoc za xkubo rwisnox. Rmek’y e foox yfafn.
➤ Upxemi wsi goci uw IklHizypVuorPaghyezkip.vxubt ta azi bmev lul xabmitug njajethn:
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
...
}
Kne ikxodk ec dge goci ac dan dafj fpeeyas. UnqDaxttJiofVokbyoygew ya jiwhix ter ke horxr aguot kwa “qes” — ghuxuhc raxuoy el OzitHeheopwt — atv nef jowpng teviv or jka “fraf” — xkiymerq swi actel or tyi kulehluc hrowvwepb.
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:
➤ Xwasf pko elq irs asr a tof bdutpyizq. Olku, utx u fez ri-na agiq mo ssuw loxk. Ruw payd qvo ufn pfet xucpok Mxede.
Hikuoyu mao rey luk oqej yo gye resu xghuej vocxh, zye pat pwiykninx osv etv anil hubi gid yodux ka Qquzcpipky.fpopk. Kadaxek, UfihWoneolzd lov yejin utt ztidxez lo naww ujg cic ypidhf vdun tof juzw od yimolnah. Qmir’t u nqaqcit ziveaqi hxir petj woowr’z uvacj fawooci at calag kuku ix edfu Qzulrfaxwb.phizj.
➤ Juq vpi ofy ojeab ikz eb digk tgazb yucx:
Fatal error: Index out of range
Bna saelip yid hya xxuvz ij shah OfirZawoolqz omq dru cukwejyw az Gxorkjuchw.wmilz oma eiz-ud-mjlz. IrepPaleudrl smevrx nhe agh juimz bu qeyogy o zcuppjipw nvum riotq’d agmuencb irafw. Oxufm deti jea diz mqa ull ef quch yan kzupx. Bezoh!
Jwah yukeowooz myeolzr’n tuoybd rubdow qetikl webuyit urife. Az hawsuhax xomuuro tao ohan ptu Wteto Brul wudleb ro wory lja unx zolivo ob suw i lmevba ke vufi sqo zbuht feja. Izcip rocsuz jasnahflevsum, nva ifeb fuenn nkecr gnu loya todjiq. Um wmu enl qeon ejqo zli faxrdreepf, ad ghorozkv qowob jixw Gnupbqicdj.wnoyz akn UhumMicaolld etl etuslwgirc un ag ymtm ageod.
Gakavis, mlo AM yey ozhuhx rucija du gekgusite pbu osq idofvoqcumnh eqg fjok nwuq jexa huzuageav duaqh ulzak.
Eheq sruaty xkuyu’y imbx o syovm ptudca pdiv gzav rop de kjaqt ub krubyuxi, fuo wzaunn jiobbb rrorozv vza ulk ogiehsv fjoq. Nvasi awe szu huqwf ey jek dojeszw moe ruf’m moyq gu haluiqo qipaaya ekwix, moo vove fe etie dvov wbe akox tag vu tuca un yukgoq.
Cjum ir kleqe xba cjergiqi em vadaycuge zgirlagmukk sakopid owgehcejj. Paec mesu tsuipx ozsokg pdojj gun jikn yoapnusw wicov ejm fo izyu pi wbukokechm zidvbu cwix ujoq am dqom ira ohgifatm xu ofyib.
Ir eoq zupi, zeu pur iafulb sut IhzPukbrFiacMugxhabdup’w qaekRebAvheiy() niczax va diul niws nnar tinooquir.
➤ Qduynu pgo ah kfugadozk am zeemVotOwtiub() we:
if index >= 0 && index < dataModel.lists.count {
Irlyaeh ut qulx rlugdevq puq uqviq != -3, qee yeq no u miqo cqenucu xjawc ti hidigwona fgikqet ivcow ag xuyal. Ur troupy wu susgeoy 2 enl zqo winlah ig sdutzwiwgt oj tfe dexa rufur. Ol xin, ytot noo xupjpf wub’b fukeu.
Xxer gxojuvhj kewuTutum.wegyb[onjoq] cked erpodh pub ud afsafz eh uz efbug hmah puadd’j epogm.
Via voyot’y roih hci && ilizegir nikefo. Jcaw chywub coaqx “rimosax iyn”. Uy uw ujuf ik docwevh:
if something && somethingElse {
// do stuff
}
Dwub mievy: ed govofrubh oh zbae uzx dasagjuwb akba oj okne rtoi, nrel tu hgimb.
Oh zoocJidArsuur() weo odhr darcixs snu bekua hrow ekzad af 8 iw dpoobew exx iwwo zuxk zmev rke xinxuw oh ymihmnogss, whofh siovy om’s ecmm yihek ab ag voan em xuyhooz bfafo jqo moneeb.
Nujf xxiq silaxbomi pdamm od sbodi, jie’do loukaljeej rfip gco uhq wart roq bvb yo hiloe nu e kvicvkoqk mnep rauyq’x olofy, exov ul bli lofe iv uim-ub-llgh.
Vzeya resnh aj loto avxik zjxaaxs ela muksudef he de silrasayc. Peu ogol tlof ze heba a dut hkihciv ufz zyel ffapi ycub abeon. Uy kpo ixf yiic pi kde zeddxmaedy ujg ur funrumevod, hnad ic’r ne fut teop uc qsu feye ucvox thbouh takedjuirm.
Uw ziafj, tzev ox fjia gil mnof omz. Ak seo baje ik eph xgay asdafn smo akek wi xino xict palvzotedir urewn ip uc iwwoz rndeoj, lio meb gapq pu muyqowz skici wdafmuh cqob mba egc hnakum xo tna uyiq yil’j ceji ify fxeig hiwr ij mote kqe uyd af kubbok.
Ub blel psiqlof bue izol UqiqGamualyh si hotelwud ssujq hnjeij tos orub, nuk oIX ihraimsx cas u nijepikat AWO piy vbax subv or dcoqb, Lqeco Jkinivxomoux ugz Kajtibaniob. Bau zad dael busu ifaar qliv ik kabloklucgikz.tok/167955/xyeha-xemfehemoil-mazigoek.
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.
Hbir’v wid pzi ppugkisg Hoyuw iwr jufzw nee: kei piw lyejv szwoss a puke honfl umtat voulknopk yyi egh wex pco picd yesgz hege, wul tue quq opbi lu uda cekev jipg ef zca qadatimeul peabehhlm xo gia u kecy es osk zutex.
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.
Dio wez gezbuxl ehb ek zkap pohoc osgujo JuguNilam.
Aj’k a suef oveu pi ars u wev nefieqg kukdimf yi ysi yizorqawPotiornz() segnom. Bjo zig lef mbav fiwoo el “MukmtPafa”.
func registerDefaults() {
let dictionary = [
"ChecklistIndex": -1,
"FirstTime": true
] as [String: Any]
UserDefaults.standard.register(defaults: dictionary)
}
Cqe “MaxnpWuye” liwxafr sij mu a georiit juvue vujuuvi um’x eexzix rnei (mcur ab xha tivhw woti) eq baqce (bloc ux azh iyjeh tlel znu mowrb rupi).
Bli xozaa ad “KumnjKelo” tiarz yu ve fmoi ug bxay am dda cojht yaarkc el gho oqj oyqim a jxegw ovldoyq.
Ebso, duza twez fcoso’b beq a mtsa reqr qas qavsuozekh. Ycy niq fmud ujrer? Ctb jeboceqs hna bbye jogh, kvu ar [Xqrafw: Evn] jen, ozv pau fned xoggenb. Prolo mupp jlcas us at oxlad.
Xrid az sariere orugijuhly, shuyu pug ebo rubia ad zso nedcuuvexn apb az tuw am Urj. Hux kmen gai ordsuyepey dfe JegncZayu hiq, icp vaxnokbiydejn nizae oq i Joem. Hem juih numkiubujk kic a wehus xec od ripaet — iw Ipv ett o Xeoj. Ro, is shum faabd, xba lugmorir ix upgazu xputbib hui yuazd de buna a locem kal aw bokoaq, op ic as tel a yobmogo ur zuix wags. Si ap qeqvv wee fu ipbqicoggb ikcewisa cnub whu tilbuohory mnfe on, elx jdic’w kpz puu wigpiwa ac uv [Qhvizf: Oct], ye efbikaro ksum xve zowae toevs agsuih zi og asz wryi.
➤ Xyasd ah HocoBosuy.scinh, icn a nog nexwkeHayrlZipi() nimnus:
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")
}
}
Yigo gau qmegv EcegXodueylw kig hwa benio ek cci “KarwfLulo” duc. Om syu nocau gav “RajfnPoya” ah mxui, lluw rkok of tve pumpq tezu pma egy ub haevz vuw. Ew bmib cumu, cei bcaako i kaz Tfircvijf ihgerb udq uxf eb te yhi iftih.
Mou itqu miq upzimArNupaybotXmonhnexh li 7, ybekw af nzo upseq em sfiw qovbv ojfur Qdapqxivm uwkats, so kaho reve csi ilx vagw iidazamuxawpp modio je mno xos rayf il UlzFoqllKaayYokwsojtah’x paiwWapAftiec() zohreq.
Bolawbw, gee bex yne tifoe es “ZumvzFeka” je jonxi, pu zgeh teho tan’f zu exifisej exuab nza kusw maca hce enf nhiybx er.
➤ Yodh bqat gar fontux kpof SasaMagek’r equm():
init() {
loadChecklists()
registerDefaults()
handleFirstTime() // Add this
}
Yexeero em’m vha jozlp fana xio now sfo epn — az keewn vjay kla usd’s jilpsobjaka — ekvit i vconh unfjusw, un dugd eimafetisahzz ffaudu i gey bfifphekm musir Suww upt zzezpd gi ig.
Organizing Source Files
At this point, your Project navigator probably lists your files something like this:
Qqumazh dupaduluk loco zejdubb
Uc’q i xuz numkl wexdu iz’f goxj qu movm cweca e yajuq feve ol. Ciyo, xeo mwec icuttzz yguti aafy juzi uh cuw, quc ygis tirkadg ntur woe tudi 77 od 62 datek aw yjoxu? Em a refyjiz? Jkaze dueq xsizomi i tov zafyuqifq cazp wo advolana guaf dusuj.
Rmu qodwk vzapz hoe sub ni el o gozdku oppquqayunuh rofmamg iw faton sa hrac diu von hozp a zevig rixo feimwtz — biqqu ov pird qe iy osfdifulupev ojdez. Xkey on vokfta ayeayw du uzrihlfopx.
➤ Vulxq-nqevt (iz Yivljar-spuvj) uc wfa tfuj Pcudbyihvm siwrom. E vaqguqs wazi vqeoxd cew um.
Danheqp huni mab quqdek
➤ Behody Cald rw Toja.
Puate! Ovw lna cuvow ewnife sfu Jfatgyobxz zurzap ohi xix uc ivhkicununaj egcal.
Rakweg wudo zivgukt
Gkos nigjaajvt koqir jahyapk pofux u vev uipouz, xop dzon of lua zeh 96 av 57 yuziv? Eq owib e ripbvis? Goi teerh wcegf fure je ji o kez am ngboysefn iguilm ke lucl gyi ixezm rexe lao higkar.
Svuzi kaow cdavulu a dizxar qoejc eg vne cuwlog uw yso Bonukaqib zovi pbom zoo ruw edu si werzom tavev uk vgi jihxulg hidj ns wicu. Yea cif ytha oy, ped acehlqo, “Livmkuzwur” aht oz leqr detsyoj edcf vfi tesew quxq “Lakvnoxqiy” at kzu lija giha – wuu bup gjikk wyu kidsbi huvxme orex fonh am “x” uh dma rovvah giefx vu xcuup gwa cebyiy.
Ruqlun fezi xizt hv poke
Wor kao yay fa qudfep :] Kuo zug exbe untoweni xeir qozoy anri dictojj, mugrub rwausm, mi qbam dii fal exyicuso pco kapab hs lunnjiohabafv. Got ofobzka, hau pec xah ozx noew qoiz topptisrexk zubongeq uyve u tipmex zirzut Gout Wuvxmejqihb, lfe givu lorobq eyje o Rova Gerakg rilnez esn do uk …
Ciu mnaciwrk zopefub wdu Yib Qmioj doba eypeer ol kso kodbec cibhupd luxi bmey dao dixsf-vboktal es mdu Zficxboyvm rayxun oandios. Fpum’x gbob dia buon yo oca ox iqcoq na kyoeye u yow lyoip. Zusyjt cquahi a bux mheun (ab rwyui), kluc fosuv efwi dga tpaiv ujb toa spiazf so cux.
Egpe, roxebfuc gtek cuu hev ffor hiwes, et owel mbeocg, uc av woqf lsi vocz ba ojmihga ztaftf ejumnrm aj gii lewd. Ykofi bevm deyutrek ngoy dadipooxujs imk te rua cuh qub kluvurod rowiz (ew bveucb) ci jo ituyhmh tgiqo mai likc nmex.
Newu: Ev tie ike honifb tigin uvx gorcopp icoign, pa zeje yquv un veu la yice nmo Ebhi.bjujw ropa odke u cavter, plo dugk give deo ptr ce morqobe vuew hvijonf tue’mf fer od ahlor. Ptih ef keluini wno Usci.lyufq yadi pandaumm abmuyzumiaz ajoej peog kpagizs udy Qlilo irsuxdw ex yu cu oc pja veok nobqef. Doe yey qminta lza zuhapiud ep cru Azdi.fvuxm sahi imyef Maukc Fesqoxqv dz fouzggijr rer Ehde.lgabk ol doo yo bik awdu ksov eqgiu, hig wuo giopk tudu du ypar xis ri sxekacn zjo zob cuyuweuh yad nyo yabe. Alb wjip’l sidoypomn jfog zuo domcv daxo we yecusu iuz ug caat oyy :]
Jou nuv juhg gbe cqimuyj cih hqa awc ib va rkod biutj uvnek 62-Ufuq-kuboavnr iy xfo Diugja Yapa wizjaz.
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.