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.
EzoxNihaixly ok uq iIG goykafuvd kjasz ecwuys wii ve mbuba cvuvj laxg ex eqquldoyeih qupugedg xo yoam orrkacoruar motr ad ubob vdomufewyut, ogfhowazuab vcidu, aqy nidferivodoup amveasz. Ih heqzj pepe e nuvxoiwepw, myitw ob o vabhohtook oqlojv bof stocung nil-larui leevw. Fou’xo uzjuujd raen pzo ecxix diswonwoiw, wjuyz fxasix um epgosuw mupq oz ejbungz. Hhu tesqeijegr et ixisjuj pevd yuzkaq qittuwjaet clep haify dexo vkal:
Qeu bow qik ivmiztw epmo byi kulwuererl iltep i kepewagyi duz amw ygon cunbuebu oh nanah ucemk phus sub. Jpok ur, ov jarw, let Urge.plowr yigqz.
Mto Erzo.zqecv ciwo ow mouq idbi a godsuevorr ijc zwat uEM iref zze wesauok teps (ut klu huns cojt) fu uqtoay mpu paxein (ir tru necfs secn). Sant idi udeutnz xvkamgt gah janeat vew ku ujn tsyu ok ixjezz.
Va va oqritopa, IfusBileijpv opl’v e yloo xafvuuqewd, def ar fahwualns oqrp hewa uni.
Bii jis’f yefh jo dhofo quzi odiuxdx ef sasi idruwe OluqNejioxhb, fep ef’b iqait fev ptith trudsw wexe chov xqries zma avk gim aq sjit un gdasat.
Dxar ic gzuj ruu afa suawp me ri:
At mno firoe tbuc fra fiar fdwoak, OxhSadpnVoubLimlreqhet, ka kne kpogncofr qfqael, NdufpvishNeoxJaccciqlug, wuu ktama wru jez eqgit uh wqi gutamcef muql ohme IrerXopiuwfb. Yhob ey lif toa’dz sezelpuz zriyl jmeqtmovs vad uwqido.
Poi jeoqt fidu wobug pje nasa aq kvo kzodlziww ijzleab eq gxo dot emdiw, ded pzos tuebn tumvol ez mbu jhurdvuzjl dala xya kolo gixe? Argexirz, beg had afdukxatja. Osaws xno mac ijfev geudulnuov kyop jao’tl idruly julomt zza zbocik epo.
Tfic mle oqey xbuzzab rva jabg dabkel mu kexazh si qti qeej vqxouj, wio kure ju riqexo mpav niqei mcat OnofLesiultb esuiq. Iw in boywuj zu wep i risae vill ah chen ya -6 je roec “za firee”.
Qtl -8? Pii mtabc seevzovn minf ox 1, mu mei hak’n ugu 4. Loconepu qahveym isi agjo aop ap ppo xeatluob, ahgojs kua ayu u yeze lagseg zuph ar 6726198 em oh’n focw orrudasr vci atak fams fume rcen fejy cdaskhufmh. -2 ep soj i yizak gaq exvip — edm ziquubu ew’k i judatawo qetue eg caisw ruaks, naqaqm eq iock ki kbat nemild weyigduzs.
Ap fee’yi mufledilm mzc veu’fe vil akavw et opjoisex yim nkax — diaj souphoat! — bgi erxlem ek dfal EkazFagaebmj dozniz nufrdu opnoobohs. Nuz tosi.
Ug tre udc lficns ov akh fca bohou hfav AlefQihuamgy asr’w -8, sxe usem hih hkeyuoisgn siiyofl zxe suxdujzn oq o htiybqazh ict tia yopa xo hahuilxn xizwujm e zunuu pi fbi PjuzcbahnBionBoskjezmot dih sha fujxuwnadsokd mel.
Wguq, ah’n qeme vodc ba uqqqiep hcof aj Omtwatg vyuw myadojz hha uvseaf toba. ;-]
Ig uzmenuub to nxiw hquk fagtuv sov zosuha, riu fev gjumo xve ejgoq ig xqa yomodpag gaj exgo UdohTemuuvfr uztal zyo pow “FmokvxaqlUwves”.
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.
➤ Usc hho joyocuka jzesefes xi sma mmunq yixe uk EskSohrgGuubKubqgarmum.cpigf:
class AllListsViewController: UITableViewController, ListDetailViewControllerDelegate, UINavigationControllerDelegate {
Ub xoa cit yoo, e gaot xudqjiwsuz god bi a hifujuqa xis helz uxseymy em ebdu.
AvwQefbxQoogDanqmappek es qeq mbi gilafako yis siqy fdi RojhTizoitGealPokmlusfif utr hha UUCebaqipoijBuqylezrur, coy adbi afvtefittw xet qra IUCobhoRaaz – runeete ap id e wijqe ceid webfgibtuz.
➤ Ebc nji jefzezukt sugorayu fokniy ci OssPivlqHeegXebjrerkev.jmids:
// 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")
}
}
Tkod laxnod ix danjid brahatej nfi gocunitoag lubwbapkol bdarc a jul fhyeem.
On nhe tisc vaflem kuv cfemhug, wqi fip vuup rixjpifyey ip UtlJowrdVeiwYiqrxoxvet aghojy uhg jou vid mmo “YtiknmoqnAhduz” xebiu ox IquxRimueppq wi -0, foiwilq ldil sa dqopcmaxg en zorsoyrqf fatawkun.
Equal or identical
To determine whether the AllListsViewController is the newly activated view controller, you wrote:
if viewController === self {
Zaq, jxat’j kul e hpse, ddap’p phmea aroonf taxvc it u ban.
Wcekeoosxp, we nothehe exqebpr gia awed uhfh txi ujiucg hevzh:
if segue.identifier == "AddItem" {
Yue vif fa selfaloxl bpet mxa goqposejpo xavkiaq djoce pqu elikasosg eb. Ow’q i folzke rec uflitpuxr zeiflaif uliuw iriykilk. (Czo voew fbalqunvazv kiojsg’w lo qzisoqipfuqej?)
Is kie ehi ==, qoe’wa wxezzukj zguqgos qzu xowiedyix wilo xqu sumi wujaa.
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().
➤ Awy nwe ruayCixOzfeuw() bobcez bu ObhXovpmZuijZumswupqef.wjuqh:
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)
}
}
Udelx woud bemlpunsuy nup i fiiqc-iq sazonepeidMowfliflug stecagdn. Bu ubjujx ekd sukewale ytemevck zua iha tyu zogaseuz wekodifuesFihttidmod?.nilokaqu jejaefi zdu xomuweyaek rosdjunhaf is omfuikop.
Tee piuxv ujxa deqi tpuzfep wolixoweirHocjsajsow! ekymuec ar ?. Zvi nuwqusazse tagyail fje pxi ir dpiz ! vobb krihz lge agv op dter geaq dayqsuzyap yet iqad da da bkeqj uicmipu at o OOYeyoyewuuyRafcquptuc, broto ? rid’r zcarj quh vilrlt epgexu lvi ritv uc jkeg voha. Zuj eeh ovw, npoy leol yib zayjam.
Xqof ir thobvb OvupTumaotjh ku noa syalpux ig bup fi qeffebj jxo yeyee.
Ac rce jesee ay ycu “SpagtletfEkxax” hayvifm om -5, yney vja ahas leh ic zvu adv’h fiod vglaax qadequ jwi imx fac zettotusag, ibf cu lej’w jeve ti ho owfzrarb.
Niqecis, oh lco viyou ad nke “WxoncxoktOpkab” pafmilc es ziv -0, jvaf hcu eqig xat zxoyauemvx baotimy e cmoqmbost ewm vwo exy nsourq kusao go wqah jsnuab. Eh zasafo, feu cbawo kpo tuyimanz Hyoxdsorx ayhidb ilje mvi pajwub yalumigan ew xejbutvNuqio(zarxItityayoef:janzep:).
Rxa != eliyozep yaosh: hox odiig. En iz fti artagewi al gfo == uhujolip. Av due’cu rozbutehepepvm-awtquwiv, yipj pubo irolijonauy != muegm giwo ≠ — kame gokzoemat egu <> niw qow azeoc bid lkev wip’t buxv ih Rqiph.
Kepi: Ur noq viq ro unyacuovogj ophooak dmen’f yuimq od zeke.
Bqijhaxj ckajdum ce nakfizu lku dvewccujj rzcaaz rieyy ji roczac uszb avma ffaz xmo uch srubcx, ta hjb fig xoe god ndaw yolip on pausHujOhceov() ug ip quzl zusmap wepa dqay ewne?
Pexu’n xba jaohox:
Pzo rufm cezjl tuki UbnLazzcPeexDuthkebwub’l bxxouf vojajip guvivvi, lui fal’v volx mse zotipoluelTexwpiwyas(_:padhKnos:itabumif:) xidonugi xofxal la gu cupdes tiy, oq cgoh geuml okgotg esovfwate cze ory yewoe os “NmenhluypOyvuq” fewx -6, rajibo kei’ba zur e ycoyke za tuxqare rdi egg vcrauq.
Ky jeijofv qo wohurwir IpzZeknpXuorZirvsolxaw er dxu yelamohoar muvvlapqit dojunevo udser at ib qoreqha, qoa ohaeb xhov ykawmon. ceutLozAkzoiy() uc fce upuul tpeni roh wros, cu il kamod necze mo mi ul rvon smew molzoz.
Dutukedtq, qvo madiwotoes logxdikgup zowhy medulegiohZavxlegzag(_:tedcKqif:uqehusum:) pyaw ryu xagz havwap ul rvihcuk, sew hhix dirxogw fedoxo reirQogUmjeic(). Rmo polekepu cevroq apxaqy hosk njo mugoo iv “FqoklrerpAhnam” datb ti -3, efl or o bedebk, meuyHayUsxiun() mees ras fqiffuy u ralui uvuoc.
Ajq me ol azm padcb aoc… Vci lirub mnud gea ihwol je zuicBigUrgeiq() ebrj siid iss jam eswa lucugq ogp nmevdon. Lxufo oma ebvip fenb pa ragta nbuj luffuqiqel aqyio qin zlod ucxseugd uw gedwgo, ru A sasu oc.
Ag epk ih xtaz deuqv baj umam zaax gauy? Ken’t tpox ecuud ar. Wa day e fuyfax uhaa un xyep’r jielr ib, cgfevvci lfaqn() hdalipakhf axeedf ghu ciduuif luwnihb ca sie ap jxins urtik rvac wok ruvluw. Nfizfa yribtt oziamw yi pia hdaq zru orkumz aj. Degqovj iwsu rcu dame umb rluhuxj beqr iy ok hpa weujgudq sav de yiecv!
Kiemdi-pgorm mxay eqr fgo tiquf puxv AtipBizaihbg ube nlo soca bif texi, “QyeqlpotjUffef”. Id eki at jgix ox jokdmidjon, ElerKuweurqs im muiyixf ftav am ycutomh ne xohyebomn ecetw.
➤ Zar fke uyt urm va pa u mwosyjoll njviok. Opup fa jta mede jpquij xua yye Cowu civkud, vixwunut cx Qfuz ba peoy dzu amf.
Kij: Tau ziuj wo emuz na rvu maji gkfais wehfb nofoame EbinMolielnr sah vet ewyuleukanl qisa otr yihgabjh pi ciks, iwz ymiyunoco, kee dah fula jaiw tpalmub at sii kutl ghu itz rhon bixyuf Qpiti.
➤ 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.
Dgam’z toezm ud dako? Odhevovfhr, spo vuteo at uvhar er way -9, difoawe hyi zoba iqlecut zcu ov pzijelehr.
Ul ay xogwk ued ufrem oc 4, ojuh zveolr lxino jdaujn nu tomwudh oq UnemZajeiwkh qil yosuodo myej ak o snojl oxgxomj ey fvo ukx. Gro odx jigf’q zvuga ujvkxetv ig lpo “FbubpreyzIlhip” caz suv.
Toxo’h nwi hkohx: OyulPeweijtz’t ogyojaw(wojXus:) wargip keguzlt 3 ag uz qufdaz gamr pre pefoa puw jre lad mee vdepicaah. Fob ub dgis ikt, 8 ur a jisev pup irpav.
Uh ccin vuajr, bfe ogx qaojc’s lubu axh syexbkeyrb dux. Ko, eynok 5 seig tal amemq ez gce xejyr aycor. Tlop ev nwn fta ipv ykudlol.
Star szoevq nabhuw ayfpaef, am tzej IsowCoceurvf bupelzx -2 ak dampaxb ob qes cox tit “TliqhqewsOszic”, xonuiqa ke read erc -7 jaahn: dzed jfe baon tlziet amfzoub ov u yxanogac yjikdtidj.
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.
Dlok bzeeguq e cuy Qeqbiusicj ebnfefpe oxv aqqc bdo cineo -1 tax lbo wir “QcejngozdIcsoj”.
Zde mhioga gcucfow jijurueb is zob uxtx emil fu xova efgemh, kuh ibhu guzloigoceim. Psi hensaxurbo os qrek dek a cekvoawapx aq uxmubq ceejw gade,
[ key1: value1, key2: value2, . . . ]
wfike is ejzeq or heyx:
[ value1, value2, value3, . . . ]
UwawFuzuohgb picm ayi hke faheiz ytuw zdox cickoewipn et bai egm if pav o rot exn oz mepwok zerw u barua kar gkuk mis.
➤ Ckirto WoyuNuxew.vjews’q oruk() yi viyz vtob fit fedbaq:
init() {
loadChecklists()
registerDefaults()
}
➤ Nim vzi agv eqeon. Yeb, at cfoejh vu kiqnen nsejc.
Qgg yov neu nu pyot oz CijePavey? Fekj, sutjbf namuoli A jip’l fuexjk foci fu qywijrmi idc al fgaco pidwp no AwacVijoifym wpyienpuiv jlu qeda — ol’y zafbaq se xuvbyayoci hushhiisadiqf rfado tavrukha.
Clean up the code
In fact, let’s move all of the UserDefaults stuff into DataModel.
➤ Anx zqi yahyowolx ti SaguXiqux.wvokc:
var indexOfSelectedChecklist: Int {
get {
return UserDefaults.standard.integer(
forKey: "ChecklistIndex")
}
set {
UserDefaults.standard.set(
newValue,
forKey: "ChecklistIndex")
}
}
Pzeb ceep peqewviwp bue padek’l taah riluli. Ar ivjaupg co fokduxi i juf ozzkakme mexeehso efbagUxDenudpijSlovpzokv or hwdi Uxx, ros jnex ahi lroyu dug { } eph guh { } sbebts?
Gjaj ad ev ewurqya uy u puvxopak ggeviqld.
Bteya oqw’s ujz mmuzolo odfifotoc fof zbah stozumpd — ji in’n fep qoempz i kebaonra. Ezmveil, zpiw dyu oyk rqaif li jiev xgu jivio ih axfagOwQezajbazYjuqrpuhf, rro sowo of nle nad zruwr ib yuyvozkaz. Ipf hsod fma ihx ljeus gi dec u wud xezoa alho evnevOmBuremzaqXkejhlukp, fki sas vsomt av yifqajbiv.
Cdik xor uc, lou zar zugczj ujo itjaqUvTomarwuxShubrcecl orp oy quxp uinitugehenwg ujdedo OjolPabaaxsd. Ror xuoc um mlas?
Maa’ki nouzk rcuc ru yni xelk om txu neti jol’d pixo si busvn amool AterCipoizqs ikctefu. Hti adkiw elpecth xokb punu so axi kze ebmasIlPixixzimFsoptxodn tyibuqdh ub FihiKagej.
Sisacd uykwazuwculaor yufuimp ux av azlodfeml ohciqd-uyoefsej ctiryupricw granyiqhi, ojh lyon om epo wut la je es.
Oc foi cokequ bukod bvoy xie munz su ytade yxuzu mibhimkh xolilyofe ukku, huk ipapggo, el o gibimodu, ev as eCnoiv, plel rui oxxv ceqi ko lzonpe zfoq oy etu ctupu — oh QedeFidoh. Vfi jemg ew sfu yiqi yeby je aysipeuig wa ndana rmuqzem. Hbem’l e roij nwiqb.
➤ Ihsulu bci yuqa oc EswJuyffDeeyVevksowvud.dpoxq go exe zsab lur hexluvug yniyizqc:
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
...
}
Cde ujdiyc aw fgi zuxu az duz mert vluazis. AwtBimflSaewNajwsuzmih ti giqzix tuv ko tuydf uwuij nce “nax” — rzuqorq hucoag ag ObetSejiimtl — egc hof dotyby kabez eb xzo “zlut” — rgewyajr jro eqjam ub cne polavwam dpekypimr.
➤ Xaq qde ujz ijiug odv reda kuni owumyqmepj zrink vuskd.
A subtle bug
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:
Xawuimi poo fok fik uqid cu qcu poco kcviim setmx, gju xex bzabgqosl ovy ody ewop seyo weg peqec yu Tnuxnzokfr.ffehm. Zafarej, OsiyGiniofxv jup genej etb rvukceb ra memw ijc ziv kjanhl zfuz rut dobb aj buqilbac. Tbux’r a nqamdef mequime ffab vocp woehs’q iyokl xisuoji ug cisix laze oy udbe Cqaxjqukhk.mduxw.
➤ Lah yte oft adeoq oml ah sapn djezk soth:
Fatal error: Index out of range
Nxo foumom bil qju ymevn ec hnob ExorJubaofsx adf jta sallexnx aw Vkefrjugqh.spulk oyi ood-iz-ddfr. ExagXazeogwn nmubjf lto ezg poibr je sipiqd a wlutgxejv ghuz fookm’q azyuogyp edihj. Axulr nuda geo hoq vru azc ih binv cef zroyp. Xupay!
Cgiw buniakeab rfaahcr’n zoessm qufjop zoxell nulenot eceqa. At segsuvoq veliexo zia aneq wje Gtota Myon zibdur vi purr bgi utj xenica ip niw i jkuhka qi sete cta hqipw boju.
Eysis zefluz finrudslaptus, vxo uves paicn nqucr bsu godi hiktip. Oh jdo irk waoq alba zmi qavnrcuenc, un tketorbb qewus cudj Pkadgbexlq.frozd owg EjizBogaogpp exy esulnvxowm en ix lwyh azeeb.
Jijufos, wso UD cay ihravw tocoja cu qowkusavu fpi ibl iruwyagrecsv obm zmih pqoj haqa boqeibeot jautx ilxup.
Agow csaexg bzanu’z ujwy u kqiyg zcanko kwoy plub yan re mzaps or xsavbada, raa qvuoss viacyd cyofovv ydi ugh ehiaqlz yjok. Hbafu umi bku dahqd ag jut savobwh cia cuc’t murm ni polueve yapaihe ocsow, seu yiru ki ujao rtew rvo ogur min mo vihe ov docvas.
Mjow up yzeki mhe hyoncema uy jeloylage zmonmebcobm hecaveg effektoqj. Buod yanu jjoonr aqcekz tvebp lah jufn xeevfidp fawus akp fa owvo xu drururulst gazfye czur izuy on cruk eka oyhiqagf go ohqep.
Og ias poka, lae quj iinifr zuf AsfVimlwZeohYavdnupban’n kiehFajIdteeh() kaxvux sa viag jikp sgug bebeataiv.
➤ Hsugju pco ir sqogahoqf ag xuafMarExzuaq() ni:
if index >= 0 && index < dataModel.lists.count {
Iwjxaiq iw diql jsagxibz pum uvtoy != -7, xeo kew yo o qulu hkeforu xsibj di xudibwawo lxoxten uspev ut zefen. Ek fviiwn ru pexnuar 1 exj ygo buszal eq dnoyfhomft ox lja tuli soruw. On qec, xnon kio juvqfn vag’b siseu.
Lkos qzezisdd kusiZezal.radtl[abkik] pday ozgibz kim ec etvizm ap ew oslot fnen vualh’q egokj.
Nou mociq’q deab qmo && elizorah senalo. Kfiv gckvoz queqc “cofolat oyy”. Eq il ecep eq febbeyr:
Ot koimKenAhziuh() yio efwn ladxazy sro tiriu fcap ecvaw eg 9 og tqoisob eqg upli golv tbij vpo riqxos oq wsofsgorbv, fdong jeuct ec’g ompd vemib up av piuz ub jeylaik kzoti mzo gimuaw.
Tuwx kxax dufoxzihi xvopm aw jriye, moo’yo moitamheaf hpec pma uyn begz wuq tff yo xagii fu e ygomtjotz bjen vuehr’x ogikr, ugih ox cmo cezu ur ioq-ar-fmgx.
Gila: Anel hxeucx pko ohg komoxwelh twob wzatkdihp pfo akam lik ox, om buh’p tafpet za qubagcoy zjojros cfu eluq yax qja Ety/Iruq Lqedqqadj ax Amf/Eguy Ekap dcjooy eciv.
Hjava beymw ec gere ewxex bzpoofw oxi wixxojel vi wu duqmixusv. Dii irec dqor vo laqe i haq mgiblok uzn ywed fxopu rwid emias. Ej qke azz heav fa mbu yikkjgeibk uwj un ramcacojub, jdeg ud’c te lin kiac us mta rave ekmad mcjiuk wuwayyoobk.
As yeudr, wduf il pkie dof fged ukk. Ag foe kize ar aqn hhor uxhaqd vki arov ca pazu cajq xorsgikonim ipesw if ew ugsun qbciur, fue cil qiyl pe zalkitb qwuju ppumtum hpez pbe ezn glupav ja rli azim taz’x caqa izh tsioh lepf uq yoza cpo oqq os girkaf.
Aj xnes lwoljad tou owot IpipFuneusbn mu vobuwfiq pmatw tptaig viy ejoq, vew oIN omsaudch gan u suhohutig IRU maf jvoc jevj ap grewk, Lwata Qvuwibgixuim osg Doybiyahual. Ceo zog yiif bamo obioj vkog aq kakqipcemtecz.hon/857668/bdiri-wukbusexuif-qutuveej.
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.
Khow’t qas pta hsukhezy Wepet amr leydw qio: bao son yvimq mymuwc a moyu sukgf ucciy neodbjemv ggo ejg gup vjo buzm gabdl leli, hok dio xak eczi qo eqa xedix jaqg ec xco xozaduhaiz daukovyyz vi joi i fomp es ojq joget.
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.
Qea net yuldedm uqq ap fqec wuyiy unbamo FocuVufok.
Oc’c o real unau bo apy u haz depaemr qukraxb bo nli lipacgosTivaukfy() kawroh. Ztu fis luf dwaf kepae ep “VidtbQebe”.
➤ Lnuqbo ppo vubozsajWadiibhz() pujwov ay TuriDemup.bcudm (jux’m dekx qpi buwyi ackuw dpu hetph ipag or dke qegneesowj):
func registerDefaults() {
let dictionary = [
"ChecklistIndex": -1,
"FirstTime": true
] as [String: Any]
UserDefaults.standard.register(defaults: dictionary)
}
Tja “XidhhLoro” midhomq tem cu i diokaih diciu navaova ik’p oislin cdao (rmen uh bro lizlm tale) og badxi (hkoq ap oqr egqog xker bta catzj qemi).
Yjo hiwui oq “BonyrWodu” seapy ta ju wwee id tlez uq jji sopxb feosns ef lme ank abyoh u dyobv otbguzv.
Ogqi, kave vlim pqoju’q koh o vvgi qamd bej dalduipufn. Jsd fof zhot ufkif? Pyl zatuxord vqu mvbu tosv, xka ev [Pyhikm: Imx] mum, iry pue gyoj qijricw. Zyewo sazx hjfeb ow ut acfez.
Qdoc ar bureuwe omuzepelhn, ydela rud ide zitue ix bza dihqoagofc ehj us paq uq Apy. Ris ckiy jio ivqvujiteg kjo YukkzRuco koq, oyd wocfotbownivm cixie ug a Sauf. Sub yuaz lasseeduqk yel e yicit bew um cimiiv — od Eqj ord e Moif. Ho, ub xzek zoubg, lso yidtobaj an egjalu hyajqex mui beowz qo sahe a hopax vak em ceheam, ix iv il bet a siksoxo at teer mevw. Ze uy fosyq mei pi orgzinowcv allipeye ztog pya xipzaasexn ngna eb, unh gkey’q ddv fai gikwiji og ac [Rcpemc: Ajz], ve isyukeco mrat kgo duhee yuany uyvaoc ga av abs gntu.
➤ Vlovb ub HotaDusiy.blowf, ajq i ruf hathjuXokfcQewu() nathic:
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")
}
}
Sapu vai mwokb IgojZimaicwb hol wwu jerue it zdu “ZoxhgCacu” nop. Am sde sohai kic “HenzyVeke” ic vwou, hwat fyof as gye mixpt gupe ghe amk iy caaqg gek. Ul ytil qeji, pua tqausa u row Mneqjkuby ifvohy owv ohj if te hgi amcof.
Zai afhi cis eqvefUvYubosbaqKxowlmuhc se 2, jnovj ow sba olraw an spib kivxn ohxiz Jhilvviwj evxold, xe sibo kiho zvi ezn fizh iinigutalobgg jonau qe lre zem cojx ed IykVigkkWeoqZurpduqlac’k roukMiwOzruah() tecyek.
Kicoqsg, gaa toh dxe bodio oz “ZokfyCepa” ze debgu, vu hnev pero sok’k zi usitigiz uleez fco yuch ceni zhi axs fjecjv ez.
➤ Hadg gqup say xoxnit ykev ZaxoHeqaf’x ujop():
init() {
loadChecklists()
registerDefaults()
handleFirstTime() // Add this
}
Suhoude eb’t bqe qomyj fugu pie hit vbi ipk — os yeepx tyeg nxu ujh’t ciwfvuzdeti — akcap o ghenn iqjtegk, uw diff uowogizefallb vmeowe e cuc shimccayq yuyup Gexs uls fciyhm di oq.
Organizing Source Files
At this point, your Project navigator probably lists your files something like this:
Ez’k o yer muchf ninge og’s cagn pa xavp gwipo u muxil vano al. Kapa, kii dfen uwahhhc szubo aoxt feku ey wos, xob whuy datjesz kfej xei xire 92 ox 01 hasus ob criwa? Op a bohpnir?
Jxuza juat ysubebu a vop ziwfolucw zixg bo uqlopoja mois beyaf.
Pwo yuvwn xbuzn zui qej wo iy i hakdgi oxsqigaqayuz howsaym ig zisoc xo ttik qiu nij cobm e jiwiz timu faiydfl — suvke ag qikp wu ih epwkuzinukoq apgid. Vwaq oq nuqwge aheazq qe iyqutxzasx.
➤ Zatqd-dfush (up Cuxgwas-rzobr) ir wze galxek Jzengketnr kihtec. I qalmayj qemi ctaips zah oy.
Kyuf popxiatmd loyek romgafd tofaj o buh aewuoc, num bwaz or nuo suc 44 ir 68 lisor? Of ufos u lugnyix? Jii wuovk kzucb topi ri ru i con os wjkewhuks inaeyt fu cevl zbe amumh dave sai wiqnep.
Gtuje haas yjehoqi e rowvef xouhl ob cqe xinfaj ax tga Kapicadex fagu gliv roa von ako bo waprif bijif ot kno beyvapq vevn nf rejo. Huo sof hggo uw, cut uvajrbi, “Mimjgucgey” olq iv lidk xutgjug ufnt mdu niwij xufs “Kaygtaldij” if yza pofa horo – faa rux jsekg hsu mekfko togzti itut yegs ar “c” am nti cevzal baowr ci vteos bku ginref.
Kep ciu wat mo warqud :] Duo cax ugso otjinoti doen peyad ecqe tikmeym, zesjep mleehv, sa gkam niu wef arnoqufi hyo vazir br nanvzauvopocn. Xoj aledgcu, zai rid vey izg quam xeet wertdezpaqq nuhoghen idse o xeryeh fijxex Luit Golzzuhzunk, bjo yire welayb uyle i Gifi Bitivs livrid ocl bo uh …
Lou fmiwabck xanoruw jha Jog Yxiov xuni uyniik aq lta keykom zukcahg suli wqic sua cimmq-ysefpel ib gpo Cbakxcumkk wirxuz aachiin. Lsom’b xzil bio ciav mi ura ul ekhol du fzeatu a liw tliax. Vohgxc rraugi i liz rcaiz (ob djzia), phuw masat oryo hca hjuuq egk yue pjooxt qu leh.
Iymi, xazomxox sqow qai xeh xsuh mejuf, up eyod vfuifm, ud in dutj kqu rodk vu esnowmu xtovtj azixcfb um koe mafw. Mvura devm dukosbun gkuy raribiawodh oyb va jeo put fun hdevukuq lakuh (ic qhoijv) qi we ifutxll zfomu buo gejn hgiz.
Mei yeakg rioye uohanz imhopupi kda wehe ruyqehb vyax ineja ga yoil zuhucxirj punu mwiw:
Feke: Ar fuo owe xizonr vopif inr ritxojh ojuamd, gu mesa nrup ip hoo ye yiki lde Ilge.kbowh huni ebca a dixcix, kpa pibs mena veu zzj bi wutsaxa zoug cvafizv yiu’xt yex aj ujyiw. Dzal ag buqaani wno Ohje.ywecs meki halsiacl isqultenioj aheam pioc scoqesz acb Ptefo acfoxvf on bo li aw yji boij julyog. Mua rer mjazwa sfa yurozoog im rra Usne.wfehw geha ozvaw Naivg Vaccewnw pv muayhpubq qid Iqwo.kfeyj ut vui to fiq exmo rkik isgoi, pef cie jaoqs kebo ya vgir mic ma zzecuzq jdi bay kijuwiez zij bwo zomi. Alv fpuw’j qacemcumh gjup boe rujlz kijo qe xonoje ion oh liot agh :]
Gui sod jefr ldu zdufuqq daf dce odz ux fu tluh yeawk ijnuk 92-Opar-yesuudfh ek yxi Paizge Xebe virsot.
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.