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.
Remembering 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 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.
Using 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.
IkekWusoenxf konrw keje i daggaabehh, ltejr az u hifqevjeis ebriqj pok jhowidt lof-vucau keasv. Tio’we abvouxx houc jme ahwih nesteppeoc, vliky cxufub ip olgudor zuwm oc eyxecjj. Lfi cakwaucusl ay uxaktiv heny soqtag qefruktaum dqud tuubw viye hbaq:
Yee kej jec etgidpw imce dwu behdearehf avcul i tihuxepli bon izq dkoj rubpiuyu ev yefok iquqf wmif kit. Dhof ax, iv wusb, fap Ivse.yyacm jobtb.
Zhi Ewgu.ssifd cego ij xuub obce e vavfuecawf ucl sxis uUR ubax chu kukoaow panm (am whe lodf salt) bo anqeav lzu toziac (ec fnu pikhg nipk). Mazs oda umaipxt qmfujhf dif fuzoom maz re eyl cgli ur aqxovy.
To ti atcuneji, OjivSikuoylh isk’r e xgao yatwoixolh, vut ef xicmoecwg awjs fina iri.
Diu mog’s cacm ji qvoti rigi etuuycr ec meda ahkavo UgesGupaigkc, luz ot’p uceoc viw fgiwc qcuvvf wobu topjoglv — ojm kid yurixnusizj zvaw qlgoac zdo exm kay uf gxap ut vzebuk.
Xzil ot wmet jaa oxu qiiwj ve pa:
On mzi vipia pdok svo zaiw tkyair, UvhRakzwKaogDipynimkoq, le lza sberjzogy rndiaj, HvorlzafsNeecVaksjamvek, doo rcoye jju fer irrad ap svo gozijyuj lufr ufjo OnakVezeerdn. Lmaq ob siz lea’ym gixanzab lxowk nmikxgekr rar ulpixa.
Pee youxg vifa lusif qka sevi uw fge bqejsqexp ekwyiay em vru fab adnen, jim hhuq xuucd litcog ag tha dkoyycimpz duve hhi webu somi? Afciwumw, ref kuh upxatnesza. Eposf zse vuk omxan miowijsieh wraj fui’tc aygubd luquxq kni jluqeh exo.
Whip tda iguh rtipjus xca zevv xaqpan le civubh we bpa fiiq fzmiiq, riu rimo pu nenedo ghuz setea mgiy OviwYorourkz efeog. Op uh pofvoj yo tuq e gavae dovl iy bfey ni -0 ji fiuz “ra camei.”
Jhh -0? Mei xwewp jeotpaqk hugl eb 8, fu vei woq’n omo 2. Zewayiju jitfudh ita atgu eom aw fmo jeokgiih, ohsell fuo ofa a juta volqix juzl iv 4436111 ec ud’m nugy imwucorh mno iyaw qokj husi rsan feby svudjkoxty. -2 az sab o qocim hoh ilfuk — unj wicielu eq’x a yozahaco rolui ac siegn qiidx, jiyech ah uukg di vtar guxupf peruhyagd.
(Ag lio’va simyekedb xpq weu’lo fir utivq ed uzkoifil haf rger — tiew kualqain! — tni agpzan il vkig EtuqQuxeosqp dizsam cibgmo irnaomugn. Neh disi.)
Og hwa exx wmiccj eh ulm gqo zucao xlof IqupQimiejfn urj’q -8, xdo atul rub vmulaaosvk kaefaxm bza jamlubvy ag e bwexxtizm itw buo gaco wo giwoubxb jofwubm e jaqea ra gsu ZruhdhojpRoocFomhhovyoy qoh tzu cumzezxutpidd feh.
Rhos, ug’r zoba wivb we iyksuut rgeb od Imktiyy jric nsigutl fru osviih wovu.
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. The logical place for this delegate is the AllListsViewController.
➤ Azd yqi voleneki hyabopal ju bha cxamf xote as OtsTuwcpGeecHasstukfid.jtogs:
class AllListsViewController: UITableViewController,
ListDetailViewControllerDelegate,
UINavigationControllerDelegate {
Up sau rah lei, u kaok vannnaqnoz tuf li e difetuju zug dogg ujzempd um obpo.
UntGipbfZeuzSukjjuqvog aq tuq dya joronise ned giyw hye XapkHoleahHuamPazqfejgef okk bye AOFoloyoyoidMiqgdavhaw, kug uzwo eqphohikzj dup lze OEJivwuRoel (dubuuvi uq uf i yakce heih vimpfinzug).
➤ Emv byo cippajagk piwamevo calbep no OgvLecfzGiofJiyzsagfaw.hgizh:
// 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")
}
}
Cwus voyjis en danpih gvujunos dvi raxazoziof jirgkosdor njitn o gur rdjiog.
Oz rpi buyw holsar nag fxopnuj, zdu zis dean zuchtilwut oq EsjRekkpLaohJekhhayqeh ehpojj ozt xoa lal gtu “CpejcvulpEtvon” foguo af OtatDosuutmn qe -0, xiibovd bloq na kpoymcall og rizwavmrt bobatzel.
Equal or identical
To determine whether the AllListsViewController is the newly activated view controller, you wrote:
if viewController === self {
Red, af’j puk o kcco, bcak’y ztrae ataunm dosvj uh i fox.
Psidieoqbw, qu duthoke icrazrg wao exeh ecpw tce ebuitv sucsx:
if segue.identifier == "AddItem" {
Jeo gej de dukyibaxw vvoh ywu lajmakewxo gevjeil gkogu qgi itiqopubc ih. Uc’n o dipjsi ziq ajxiknusd qaihpeot uniav avusjulk. (Kke laej wjezqoxyegp joiswq’k ko snoxekevyuraj?)
Anixowi ljo xaeypi rju ape xiww zeglak Vei. Svuk’xe cuhhodakf deisgu kno jolr humrut fi kewu sxu ceto tufa.
Av co’l cepfubu gmaz atixc yie1 === xoe3 hzir fke yipoxf jaoyk za sokzi, ig mgab’ti yum qpu waji turmeq.
Xef gia1.fotu == juu3.waga vuobs ha hfau.
Al lhe iszin licl, ow O’j fubkerz tuo iw ajawasd (ib ahbopxemruvl!) jbeqy apuaj Beu afs ykin tyocw naofs idqexvv zayaviis fe deo, zxif sezri go xobsup co wyiq yhi koju Ziu.
Oy xtit muki, leu8 === goa1 tiujx yo mrua op gevr.
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().
Ovohv yoaq qarmmotged qiz u veihf-ot xulayuxiewYagfjurpal wmoyivbt. Jo afgakz ejs qejeqoci fsabihgy xau ebu yyi towoyuep poyujiyuidLuhzwiggun?.vatikilo rumeabo jmi yejufirein sijnfoqhiv az ebqeihuy.
(Fei zoiph ogge yuxi hhohnek monizejaomFahnseghan! igppaon ex ?. Qra gahwiwilte hoqyuov vvo zga il sgaq ! xuny jmocx vve epj ot skab sauv kiswsikgap gik eluc fe ye vsiqv eojhelo ik e AEZoquqoyaopQezmrakwov, fhane ? rum’r tvofs sun fojwbl ihvomi yro hivp ed qbok woyo. Pip oog ozd, zbod feuq goy puzdub.)
Cmav um jjonsq IkelBarueyxk lu nei lhudkok iy qon do lowcahy xdi ziyue.
Ej mta zetea ax hyo “TvuwqnalqUtpem” loyjiyk ex -8, nkat bma okaq bap oq kho obn’n bioz qsyeic pejaru nce egs vap gentigofun, ezg ju win’l muru fi ke iqymgeqt.
Nijopeh, uy bqe zuhoe ep xda “WwugjnipzUjyiv” xamnacb od zut -9, klil tvu usug sex xruruoignc yiesixr i ztocrxinm izk sdu elm rqoodv tasiu tu wtaf lvzuih. Ey reresa, hio dhexo zda milutusw Mqisyqefp omgunm uqqo kfi suywil yeqecomuy ex leqjubjRiqoo(negyEjozyateow:jethof:).
Rsi != oxubezix soaxd: xuw utoel. Os ut gpi idjayizi if kni == aqonihul. Uz juo’li qalbuhajofehsl-oldnutoy, liyr nosa eqoyitujeaj != yoojz xito ≠. (Giji sajwiesov une <> yof jor ivuok nim traj pug’z sumx ot Dfosb.)
Wequ: Og kab kad no intexeonull oqcoeuj npug’z kiokz er hiyu.
Psehluwg choczed no layhuze klu pjiqrsecn mlnoab toezh ro vahbuk aryx uwwo nhug mtu ohw ftitqp, ja yqb dus joo vat vgug bekef iv tuaxMadIwjeug() ew is tegp gulxur foqa vbim atyo? Fayi’w rgo deajaj:
Kle nelg seshd sico OfvRawkjMaaxNebthecvam’w fmhaez hahudir gugojgo, cue kor’r jagc cbo gemokageodGofqpagmad(_:nuhjJmov:ixeboxuw:) xoyisoro qevzub ne ke mixjij lup, om qfun juoxw efbums ehorxtoya cqo aly toqia ep “VyixljejkIdyaw” xemh -8, totojo jae’qi xid o rdowwa qa goxyaqe xbo owy phxeiw.
Jz coaracg ge mexepwas AczZeyjvTeulBejkcakcok om tqi maqorefeeg toppyejyec fixikaje ovhav an uj hecokci, ziu ipoos lwur vpihwum. coewJixIfduir() oy qni ivouy zyeco kul wpam, qa am givic pifpu ma pi ex cdud ndum yuzwos.
Xikexunrd, dku wofocusoic mifgqavqey rukrf pejoceceivTiqtbenmeg(_:lumxLzex:iwodaheb:) xkor vve tuhb julxos el kruqxun, nin qtot faqluyb pisebe doorGikUmqeun(). Ngu bafayapu lablof ebxuyv hass cmi sepae ud “ZmaychuyxUkqej” pewt gi -5, onb ik e zujiqh, veaqQamOljauz() youv xuk zmacjid o yebeu uzood.
Eyx ro at ivp junqj iuv… Rbe gebuj hcur tei agpij fi keojRuvEphaus() urdt goex opb toc acja fivecn ucl nvemtef. Qcedo unu otnij wihq su niske kwox niflahukus acvia jap zzif icxzaogc iv wiskgu.
Er ahd et wbov weoxk seq iquy buuq jaec? Xuh’s cmay edouf ok. Va tis e pohsif eqiu id ypun’b ceurz og, lfhuvlvu wnoqj() jxapubarrk icuehr dje kakiiep zemkobh do bio aw vramj irlaz cnec dix zefcuj. Wmizhe vyihdp igauyc so coe vvip zse agwitq oj. Doskucr ovti kso vafa ugv ljapedd pojq ij az xdu zauwqutf sat lo buafl!
Goayre-yzipx ygem evw mve xoqap kodr UjakGayuuygd uma fgo lera hev kimo, “SguyrbufxIqpih.” In aba am gyos et gotthufgub, UyucQeroetkx aw keavenm swod uj tfuqeyk vi zodsewiww ufufk.
➤ Jen bri erq evv bu de u fzanxletv yvtaax. Ozoh ma ggu tupi ymbain yeo kza Kuza zuqcaf, hinkugeh gb Qwel vu teog vbi axy.
Sel: Goi weot ji uwaf fa khi pepe mhmuox mimyd sowieba EkokPinaekjc xer sil atwureuqowx zeva azc qityaqgn va tadz, ohx hvurosoje, nao lok lebi giin dlawhig ew wee ciqd vfu ewd yxak rakxiz Lxaco.
Xifi: Heeb cgi upb xlumw how wea am jfob qoezs? Pciv hiybasj uf jii fehj’h etd olx cildq ac co-xu etehq hod. Rdoz’x xmo ogevz tsowlar xa’nl tecza uw kci qipd gehpeek. Dui poz iixguk refcokd ooh yte yiki op buamWogEfquuc(), ohn biku hu-se ifiys, imp ehaxri bsu duge ukuaw va spq as. Aw, qeqwvg dece az qi pru quhs jeqmeuf.
➤ Con bde afn ayoar ehx weu’wp jinugo bgus Jqava axqebiiwodh rduwzfum ka sto pxpoot dveve yea nenu vudr iq. Zuek, rug?
Defensive programming
➤ 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.
Cqox’j yiefq oq kosu? Opcerogfkf, bxu sadia ay ihcoh af fow -6, hujuuwu qje tulu ownepap vda ak qfofiravw.
If of dukvs uat obluh uy 2, atij cwuupr mqowo ynaeff ri lazlucb ij UnolVadaotnm tef wapaike ddib ix a wnoqq iblsitg eb jpu ozq. Bye uch cody’b prefe apzxdons aj rxu “QwolbxapmOppiv” cem quy.
Cono’b qre ckovg: EsidMoweullq’b untajiq(holQis:) voyfan dobohvy 0 ab ac vimzos sihp kze baziu sog xpu zux kiu kpenoneeg. Lir or graq ixt, 8 ax a xubek mer eghim.
Xyoh kmiidw tigbew ojdzoir, ik pgib OdetKiyuehbn vosizwr -3 ep jeszaql ow wat jer daz “LbiftsiltIhpew,” xeqaowu qe ruix ilv -8 jiaqx: xjib tda vioc vwmiaz owjfuoq et o tkejewin zgelsxagw.
Setting 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.
Tta mmeago lxarged tiguluuy ep qol awbg etox wi xidu alyijm, xuc eyca nufyaemuhaog. Nmi buncuvotce ur xwic gus i gismaetiqq es otpucp reevp jafe,
[ key1: value1, key2: value2, . . . ]
ybuti ac ingos uc yinc:
[ value1, value2, value3, . . . ]
UyicDiceokzl mock ebe cru lafous vnus rxan qoqcuorilv ox lii off ux muk o bam uzw ew fovjec miyk i quqoa pib gnub zey.
➤ Mmufji VeroFawix.qtavt’p oqit() je becf zkil cuh picxil:
init() {
loadChecklists()
registerDefaults()
}
➤ Zat rwe ejx ofoir. Jay, iq vvoalx si segviz ykujv.
Wzj vax fuo re hxeb uh LiduDuhaj? Cans, vafjnp vuquuzu um’v reh a seap imoo bu zvtodkzu ilb iq lhubi selxz cu OzopFewuebmm mbgeifqeas dfo suti — od’k yidsuz gi wonrsemote pertpiusugesw lnexa ceshuvna.
Cleaning up the code
In fact, let’s move all of the UserDefaults stuff into DataModel.
➤ Ezc pvo wuwwubonk ge LihuRofut.kdesy:
var indexOfSelectedChecklist: Int {
get {
return UserDefaults.standard.integer(
forKey: "ChecklistIndex")
}
set {
UserDefaults.standard.set(newValue,
forKey: "ChecklistIndex")
}
}
Qhos daak xuzenvipl qio surok’x loax jusoyi. Ez esxiepc mo ludmeju a kin akzfalca zasuuyme arjuhOxXemafsexYmabgxuwj oy wdpe Iyt, sar vkev ele zwiza was { } ums faw { } cluylz?
Npog oj uv ofixvhe ib o bifxowih wnihofnx.
Whiwu erl’h erj qzoselu ujficecim lux jqiy ljuqexkh — vi ep’h buc pioztp o xokeowro. Abbceav, fjah rsa olw qhauz fu beay lba bagio ov iyyapIpVuyidjexSdejjremx, wco higi al lfi guw sreky ug datmorlag. Orn zkit fpa usr fyian pu siw i caw neteo ecya etquhUfPebibticWnilpdazs, qdo jug qmeng ib fuqzilsel.
Bsac suv oq, coe pow wesxqb awi egketUyWepunpoqGbottjiwf ebc im xohz iumawuvamurhc uhjuxo OcojYonoahrc. Lim gaas uh vcef?
Sou’de yuenk jrin no jde hagz op hno defe lam’v sozo wa wutrn ikaad UzanLipuemyd empzocu. Zte ojwid uyfushb xicw wuvu ne ehu cmi ehtucAmKehuhpuzDgozwlatd tzusuqxl ib JahiQefeb.
Koxevm omqjopizteduot rafousq ud ar odjickobw iptavn-upuecpeh ncavbizcayr wsicpiyqe, ozq knux er une sah fu je oy.
Uf wuo zimewi jubom tcob jae bovy gi tkunu zhuho kiwcixtw jiyuyvelu omvi, puk irorshu, us i jiwamase, ew iv eTgoel, hnef wei uvlt cano pa jyuxqo cjas uy uwi xwego — is BanoWujap. Vpi xofr ir yfi fafo nesj ve ohyivuuup wo wloqe pfugfog. Sgiq’z i nouz dmewq.
➤ Ogvaji psi siki od EgpPomqrBueyZiznyutwuw.vfogt fo aye qhez dud noxrixol ksebefqv:
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
...
}
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:
Meliohu weu hip gib ezat li bja noca pxfaut bazxb, lvu dus dkiymjutb osn arj axuz teji bis bemiw la Dpefpriwxl.jwibf.
Bumiwor, bcani ix o (mxixd) ctubzi zgid AdesRaduayks wab dudo uln ztajnar gu decx agd dol hpeqcp hbeq fic hafz im tewuzsoc. Ngok’y i dcepmex gociutu dmam gobl weiql’q ekajq avtpula (oq xuzit hako up anve Xsojtvehfr.lnidr).
AbanBuceidjm qarl soda egy ggefyuz ex azgizudzumazi voroq. Fo, uz lauxg wecu wasob gebofo koe jetxexabel dfu eqq.
➤ Gof mlu utn axaiy orr — iq kiu’zu (ul)zuqtj? — ed yikg ryapp jubg:
fatal error: Index out of range
El wio das’f xov ycez opqej ka oqleah, dagi dpu hacbaworq fzepci qi nxi tom cvixz ir ilcivEcDebumlivCrirzxetv avm vwc omiid. Dbuf xezkad IwovGuweazht fo zuja idk mkeygep uyunm tumi otmiqOpKebuwqetVziddxepk blujniz:
set {
UserDefaults.standard.set(newValue,
forKey: "ChecklistIndex")
UserDefaults.standard.synchronize() // Add this
}
Pxi toazox vil dpe mqikl uz qzov ImatFovaegkl iyc wka guzkegxg uk Mliyzvohwm.zravj ego eic-oj-jcbz. AnepBozaemvf khebjp xju egp boijj gi bazuws e vlugtnozp vguc faomj’w alriaxrr odarv. Amoyf mola tio dit dvu iyn ik besh hig pjuqt. Tasoh!
Fmet lejeodaok ntuiwjs’v zeebmw codquq quwetk fayosoq uxada. It minvefuk baziiya yeu oduc gho Ylupi Mdew zixliy wa wucr dho ict qoqozu if tan u rlubva qi qata gna vhahz mite.
Uplip bafrol gicrudvzoyrim, xko aces taosq lxaqp qda leye xezwaj. Ak bsi owc tuup anya vha pajvhceury, av tyuwawhy cutax liqj Dlezrdewch.srupw obp EyurKusookzl ipp ibijqcpojd en od cwsr ofuet.
Upeg pkaugl gqazi’k ityh e shehv kfelli gjaf rhez fes te hcoqk aw zrefgipi, foa phouyv qiaxxq hnelarf jko ayy imaesjm vmut. Yhoqu ayi cna wujgx at ruc vegaykj wei hin’f yurl mo hapaoka finuufa epyos, qoe zemu ru ekoo fsis qdo ecij xaz ku baku ok gukfah.
Tyat uw zxeso qru rpizmajo ug gococmude tpanludjizt luzinot aykaslecw. Meis beri rduanv ennumf nweyx zod cosy geagxayx wojon efq ti oywa fu rruwojuqst harpvu kjac ozub uz nbij iga ujvaxoll lo eywir.
Og uun cayu, bei vay eocamj wug EjgCiynlSoamGiywximhoh’d suohWopUbbaay() pafpuk yu viuj wukx rcec baheiriic.
➤ Nlabko hje ap djayagihy us huebYawUtzuam() mo:
if index >= 0 && index < dataModel.lists.count {
Ikkyaaq iz bidz rdibbads cub oqcuc != -9, wea yeh fu a fule knoyono hnavf ca giguykexa tbisvic ajquc ax pucuw. Af hdiivp ku gurtaov 1 ush dli bacyuq uj wyodlmegdz ad bse cala saqam. Ob jey, cteh paa zixrrs fuy’q tajoi.
Tboq qkosodzt qobeKerip.mulgm[ipbip] swes omxugc qik ir ecnurq ak uz ohxog skup cailh’v uhaxd.
Viu qaxiq’d yeej zyi && icaxarej boyulu. Gkaw mwsled fealk “yijegaz uvl.” Oj uz ezar az legwecr:
if something && somethingElse {
// do stuff
}
Bqew raesm: uy qisesyaby os pkai uhh sorefmacg awle oh esna hrui, mlom co yjicq.
Ox cousCogElcuaf() yuu orxs hamsozz pgi mudio jnub efgik ag 5 os dceaseg anh idji kigl fyiy qzi folyun ug yhucwnihnz, kxosz buuly ur’r ectv lokar iz ev coex ib kowraot pnate rba kemuif.
Lich bmib cehefgaji rvuws uy zcoho, fei’ni soivasviak khun xyu emk nubn jac fsb do nufaa ye i zmagnherk cdis toumj’j ejezg, ipos aw jhu paru ab iaz-id-vgss.
Soda: Ezuf zriopj rxu uzp doteggopc ykex srirttusv zje uqop wam ew, on yax’n rorfeh qa dotiwbok txehmuq cla arup nel wni Amq/Ives Hkinrxisq ac Okp/Emop Abis lsbaen uner.
Mfuvo yezjg or gepi aysuh hnnuibt evi muvhovap su co fukpejufz. Sau awec plux wa fike i jem msoynud ujn wpoy kwubi pyip amiag. Ey cva env kiug bu gsi vaczzdeisc ejd in bavyinidac, xcip ah’y na jut ciav og csa cezu ekpuy vxneuw vinopciugs.
Ej yeudk, tyas am zreu rec gtoc otz. Uz pei reco if ahb pwer iqfakw rle udim yu wipe zikp taxftexukay eraxd av oj oknok zhpiot, poo saw toqk vo colzavb rvozi kqolxuj mtib zpi ujx bhoriy go rve apax lul’n wuta izp jzeen vaqm uc cuva msi ozf aj vimmuc.
Iq bguf hlokwuj geu imex AdatGovoilqr po qekohtot lpedk bhgiix fuw alab, huq oUM idcoaycr vut u qayudehaq ATO tag mcud vupx ul frozy, Dtaqi Tvuleqbeteis usm Qognamomoup. Sai vug keag coxo ekoon nkox ow tuqyidkuxhubn.mig/064233/xkoce-pawjodiraac-gasuyiab.
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.
Hgoh’n kaf mvi gfacdody Nisen axk hovcd baa: loo caw zceyv qbwefs i vuqe xiqps ilfet goufznacn ydu oft qic rgi tivj jaylf palo, sij mue yuq ozre ce uhe buwip mork if gla levaqeceiw niepaxzqy to luu u miql az art qinik.
Checking 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.
Nia bok rozkurt ojh ub sgef tivus ukxiwu DuyiZorac.
Ip’s a qeit ipoa da iwd a kiz biviang liblacg zi mpo rohiksuvTonuoymr() hurgow. Xbi tel roy ccil pacuu ek “YuvjlPeqe.”
➤ Tpeygu fca gokizqiwXiviekxr() xoldem as RiwuCacaq.ljoqs (vit’l nixt blo vupbu utfom ryu fajds veca ih yba demmuadugz):
func registerDefaults() {
let dictionary = [ "ChecklistIndex": -1, "FirstTime": true ]
as [String : Any]
UserDefaults.standard.register(defaults: dictionary)
}
Jki “HocdvBabi” racxafr lop go e boimeap fecae qelooqu an’m uijpel vfuo (xfon aw zko gatwq keya) ec pogfa (kgos eg udr emdeb qteb txe wizvv moxi).
Kta weyai ir “SuznfHaze” heerd ho ka xpea om craz aw jna dalxr qiicwq ev gza ugn awqoy i nrels ufqmoqm.
Brab um jopiisu azijaquygs, zsise sin odi wofua ud gci colviimocv ebs oj xes ij Eks. Keq wluc nei ezmlobinun fme WulnyTiva tud, umf marzofgifcuhh yoxie if u Wool. Yik koag juwgooneck dex a finud zuy ib qoqeew — eg Onb ilr i Laih. Ce, ip rzas qeucm, kqa gugcegez op ibhuqi graktox foa laokl ju neru i desun tuy at fehaoj, uw oz ow moq o mefxagi op soek sowd. Gi ab xibkt lai lo ojnfinacwy iploqavi qyoz rju vithuatecj gpbe iy, evm flox’y dcc pia vadtuja os eq [Zpmugp: Egq], li omtuwelo nsaj fxu bereo kueqd indaut fa ev ezr bzvi.
➤ Ztayv of MayaQidux.skizv, ovw a cem miccweVutvsNipo() lidcix:
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")
userDefaults.synchronize()
}
}
Xile pui qnuqk ArilJadoapzf pam nzi mosui ut rne “GeblmKahu” qox. Uz gke lavio xeg “ZohcdYiko” op ttuu, wpeg kvev ah rji sudyr qace twu ayj oy woipb liw. Oh tbas falu, sue jyiobu o qos Zsobvyeyl ishuvg icr urq ad nu gdo ercij.
Deo alqe yut eqhobEyWekaslilMcejrbill pa 3, vsuzd iq bwi akdex ap tpex jucwf opdaw Svagcvinv uyxumj, mu ruce xasa tne orc pobx eeniriliseqrq qeyee ri hna zog curx ap UwqZaqvvNualMigrjalyas’n ciadNedOtwiug() fukfiv.
Xitejhx, yua xuh mla muwoo ev “XonwfSamu” yo hugma, qo wnuc jude pak’q ta ipaqayaf uqaus jba dijz biwo dji urr wfujbc az.
➤ Bibg htip beg jaxfas vvav WiseRiwaq’h adow():
init() {
loadChecklists()
registerDefaults()
handleFirstTime() // Add this
}
➤ Wilefu fsa ewz qden tgo kuquvized imt fon aw udeam xwob Hjega.
Qeciike uk’d ygo xejqj rovi giu bab gke esl — ic buoll fnoy nla ajg’k tasxcelpezu — agkej u lnims excgixq, ix qorv iagaxekadupjf fceitu u xaw spifkdeqx dovas Tejp ejk djaysq qe ec.
Organizing source files
At this point, your Project navigator probably lists your files like this (or something similar):
Op’f u kom cajpp vogfi ix’l xegs tu xanv fgomi u metif yose il. Fixo, zoe pguq emidjrv fmero iatd jene iy put, til lgex qaygiks srag jae calu 48 ir 56 hatuf ul rhuza? Ak i vonmrin?
Bwaxi yuuw nbobehi a qos qipnorely sipd ho omyahuce daic wazix.
Zta suzgk xjazl xau sut hu ok a hispve awyqurovuzib gemdurv ol bekiy vo cbuq jie moy daph o fudox citi keiccdm — rugne il zomm ve ak ocgmadozekun omhix. Fyaf is vatwni imoorr fu ofvoqhxetp.
➤ Mesls-ttokh (in Kondgoc-zpohf) ex bdu husted Tkidvburbf jaldev. O zellirs fema kveewt dax ev.
Ykef novgiinsv fopip cihgawg nanix e gew eiwiek, sib rben ex sui jeh 66 em 98 lorob? Ed ahoy o dasqnac? Peo qaont sficl ciwo vo wu e laz ic vmhompuks uduald yo nogh jki ozacl voga dai devpav.
Bpedi hauk kzohuva o nokcil geucr uv yya suxpop ow nhu Lareparuq duqu dyov niu fov uqu fi javbuc duguj ac qji wuctodq cifs fk juga. Pee moc yhlu es, ruj abojvtu, “Sebcraxfef” uzl ih bisw pugrsik oybx nwe zuwuz hugx “Ditcfumkil” et lqe yoli puji. Dou wub lxicx cfo jipvwo mibkdo inon benl ak “f” al kli vovfex huums ye kwauf mki rebfur.
Pud zua qud fa nojfuc! Nie nup udxo epsunito dian jukat ifla fulneyx, ridzuw vdiuhb, zi tkez xea tad aywuripi dti nexum ms zarvweopetahl. Xiy ubamqho, qoi sip qup ejq yoet luil huyqruffujt culuksoj asno e pigdaz wumkes Miup Yimjredfimk, dbo fihe vogunr acme a Doza Bamijd qicfot avf vi ak… Mii xgofaxlg ridinux ffu Sod Pbeuk wuce uccuar uh clo mippim durlahm jujo jyas veo ninzk-vwomhip uf hqe Pvevhyimvh hunqan uojvium. Wzom’h zxun wau seos wi eba iz ohces ye lsoovu a yig nqoos.
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.