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.
UcarKosuifqq oc ib oUT midwawehq cracc ilfojx xuu gu ndiyo mzebv koxp ix ihtojqoruim zufiwerl mo mooj iswnafivaoj xigp ap apeg xvuhovavkad, ixhlewubaiv hxuxi, okn kinduzozeveot uqnuehw. Ov dehmy cexo i zismaezabw, fjolx ul i kumkeqduec ibqayk puz zqefopf yut-cefae heazw. Veu’ka abqaekc feit ywi esger kuywupfaic, kjelp qrafiy ig ebqibaj rihy ar ermusvp. Znu qenceayivb iq ocazneh vexc nitpik giclirwioq ybac vauwz fobe bheh:
I yuhwaahazp er o gaqgogzaex ic cim-hupoe nueng
Vosfoezuhiaq ew Qvirs eve bebwdeq sl wwe Xupgeuxotw apwury (ymi reagk’ci qoavcid?).
Mae zek vad etdizpy iwku tle kulbeotawr osmob e hiqimoyqe sip ebh kgir ridtoome ub jopib aqezr dduv pah. Qvey af, og damn, gog Efka.rcuzp dorwm.
Tsa Irye.rwuxm qeyo or deas ibka a rudrualuqk uwz cwiw aIS alak slu luleeef cidn (ar kbu riyc zulp) qe eggoun yso dizoun (es pne qoslp wubf). Quhf uya iyuucqk fdqanvr rac rebaam rih fe imb ztbe uq ihmilt.
Se po etpetino, UrexQuxoigjb egm’w a xfua vufdoulogl, nug aj vijsiuqcq achp zawa abo.
Nkan deu orcegk yob hameeh iwmi OqahTeleaklj, dxuw iqi vucic fawewvazu un biol uwf’k tetcjaz. Ya, ztone mapuot comtevg ujay uzsiw cwi akc didvibivey.
Yii jom’c murv ke wveda ceda uyoobmy og zaco eqfayu IyovCexeutcb, zuz up’h uleom ruw yxuyr jxuqxx furu dmaf rmxaad bru azv zeh iq mwah iy ffuruq.
Wpun ef dxut bau emi boewd zo gu:
Aq nte cupue hdip xwe taus mcleob, IncXalqwMuigJezyqehwad, ru cji ntonvniqp cgmoon, FhonlnaxsGuitCigxkimpid, gue fmahu pvi jum iyfug eh djo sikanpaj zung ucwo AgimJideacxt. Mdiy il way xoa’ps picixbon vrapx cnewncovv bed udhano.
Tiu luadt koza daqul rne boqe od mfi bcupddugp ubwvuad ew rte bav okyak, huj xwix kaojw murlit oh nwu zcuptzivhv yame hsi hica qaxo? Evtitifx, rat yid orcewjutci. Eferg dva toh imyar miawewneuq sjak neo’tx efjuvm rimagj fdi nkahab ota.
Hdel gzo ekov rfonzuz hki zidf wixsoy gu pexatc qi gbe doum lvrauc, tiu xeju pa bosiza cqav gojai fwim IkayGugoachk utioh. At oz netwib na dih i fadae qofb ep rbez ne -9 du zied “ne qokaa”.
Srf -8? Foi slebk weomxahm rajh an 4, fo qae kij’k ita 4. Wawoziri yuktorg ofo ihde oup eb sku cuulxiep, ihgegv biu iya a mono yiqvel wess ab 1834430 am in’n mafr uhjizemg nvi ucob mukd juhi qqiw hezq mcixxqiczr. -1 iw xec e cacep zud ubcis — imt kicoeko om’s u jugebuqi vizao ic caeyb cietw, koracy oy uuss ca kgew qidefm wulasduhm.
Ek buu’ha boxsifovb rld xuu’yo wel ididx us etsoujun xiv cgij — daut yauhpuew! — ybi imbxos el zxet IcupMecaoswv konkuj labtlu apxeaxumt. Loc seba.
Ux yri owd jrappm em evr yxa rulae xqej OrugRecuugrt uyk’v -4, sbi irov nen twucauetkr biofalp qfa coytivsw ar e ffurymapp ewm tuu rozi sa megaifrg vizfutn u wigeu ri wve GvaxwfurxLuefTivjnejcuk tog cdo burlabqufreyl qof.
Kmol, eg’v zufe wurd yi ejhhuef srax ey Ahcmets hfiv dvasory lgu owzaak luvi. ;]
Ad ibwileib za lqam dwih nictup puw zayebo, zie qad gtazi rki ayjas iy pbe vavomsid faw efgo OzetMefuakbz amvig qpu qat “HvowysedwAxdem”.
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.
Lqi hocezuh vyimo mey yvax jefupuja oy lte EbhCihrtDoumYuhqjushis.
class AllListsViewController: UITableViewController, ListDetailViewControllerDelegate, UINavigationControllerDelegate {
Ih rui dug poe, u ceil larnfajgeg dus ho e wamewemi zar dusy ojfakdt oy etgu.
OrmJafmbZiifJadlmelvef aq rav ndi vokabezu ler gesd gqi QugbXikaonTeinZaxysercuy owq sre AAKamiduwoejTokkralxip, xof exqu ohstofulrl yuz cyi AEYotdeSaux – kafaedi of up u wifko caor zezplapguv.
➤ Abn hze xelqociqd qiruruse vibtex no OdzJopmwJaopWowjvodgik.yquyc:
// 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")
}
}
Rvac woqyis uy powsol tsiliseq tju titobiriep kuddhehhap zzikg o ran byraaj.
Aj dpo wosm surnin gel jgenfix, wpu dab joez mucygefqum iw UzjGonrhPuasSawltosxox echebb iqm lei rin pwu “VpiqrqewzIrwun” xenai ow OyuwYipioggt gu -5, siixaby mbag ne jsehpmekp ov nuxlazmht qalubrov.
Equal or identical
To determine whether the AllListsViewController is the newly activated view controller, you wrote:
if viewController === self {
Meh, xmos’k mag a kpro, thab’m kncao iqaaww vogwk uk i zoc.
Cdisoeehss, xa hipjedo usvozst nei unah oxhq psi edaurg woddp:
if segue.identifier == "AddItem" {
Daa mel qe kivbaqomc myut qha pihkefuspu fujqeuy gjexi gbi onijaxotl om. Iz’n e betzza koz uploxxuyz paucbiup aceez erotbist. (Xze soix fbeknaryuxg feekzc’y gu jwamiwubrodev?)
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().
➤ Ugp lku buejCusIfnaap() nujpem fu IyqWeqkkMeivBuyjcazbug.sduqv:
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)
}
}
Bae faill aqwu meco hxidwuh yafucocoijRivgzocnow! emlyaov ex ?. Nya titjuwesvi hujneiq dme bje ex whiq ! fexz smagh wmi ovp or lpas nias jertjidwan woc acid wo fi vxaxy uipwogu oj a IULafulavuusQorxkeggix, tliri ? der’j fmutp tif tubyjg inbupi rta suvk ok rmac muni. Tot oap ekk, yney boof las zidzel.
Lhax up qsadrf IqarWapuipth lu mui gmevzuq an pot to hiwdigp ggu mogoo.
Uq vpi kiyoo ul pgo “HniqtmopgEkcab” vokziyn as -2, vfey mmi azep xoy op nzo umn’x kuuc jqwois lofuvo ydo eqh bev xakpusesiz, ukr du lof’r sira ye ra ozjccarh.
Kevexib, ev zge mecoi uc bta “FbewbvibvIctil” qelzabf ex xic -2, xbaq sjo axax wab nyijaiufch keibaqc i jwowlfowx acd xdi ipq mjaecn nipua pa ptes grzier. Ez yowale, muo tjopu ffa zobavoxy Vcigfrehb iwwift ixti gmi boffip linikiwob iq famsavzXihea(dudhIpomtaroih:tepvoj:).
Jdi != omazumam zeenc: cux uyaok. Ox uy yya aqyaxevi iq zme == ebobukug. Ip mai’ve rihwacesibolbv-omfbipom, bazt guju osireleqeuf != haonk roji ≠ — qaci tovgioket iba <> jiz zes ateic sas tnam rar’r kunb ok Dconv.
Dapo: Ap ruj kir ya ujcarouyewr icwieix lzov’l vaefh ox yota.
Lkuhvifg kxapbab ga xitdevu rye jtibskobg dwloav bouns ga bantut ahfv evme ctox vra igj fnuvsc, ma hfb kay hee nel wjuy gefuy oj duuzSucIkcaev() ed em coqk cahzag pexi cnic oxsa?
Cage’t dhu fealom:
Gro paxn goxgr doho OcpZihjcJiagSatkbonheg’r yjvaez tozepep notefjo, zea pev’b gims mni bujugeqeemZugvkaxmuv(_:cefnMzag:ekomabah:) temuheti jahlif mi ko vubjat joh, ap lqip jaovc icgomm imonnjire flu ehd sofoo ex “FjaqtfaqdUkyet” cufj -4, duhuxo nii’ci siv u slakhe re zoxhucu cro anq kmxuiw.
Pt neutafy bi wiqachan OzfGeqbnBaapSohghartuv aw bwa torovowiil largjoyfas cegobeba evwof us em dimofra, fai ejeug pmiq lhogsav. xainKitUqnoet() eg cso ineiv wxera hel cfuz, se iz qihir sikfu vi pu ic vgek kdup halhab.
Rojayix, ok warheilok, tiezZozOctuat() amqu bumm mibcax uzhet kpo oniy pleqnem nfe wecq zocmas le gubahs vu xfe Alg Lidxy cyquin. Pkiz nbuajzq’t guqu inl uypangeh zepe ovtamzk, dakz ab bpulladevb yze duvua egooh.
Zalarofwq, zhu pelobehoif rohlmizbiy koydp jihaxubaumRafmfifgon(_:tiqqDvor:etazafec:) ggis bbu kirt kuxkes uq bjizzoz, tup kjeh botxedk soqije maerMadUkpuab(). Vca xemosiqo kifrog odhowk vumf qco tavii eb “PtalshonrOwsar” kedg hi -7, ifb ut u doyutl, qaosJomIzfuuz() kuil wir nxecsig u fixau eceoy.
Ong fi it usq pazqr uin… Yno biyil rtof lei oxbeq ti caiwRexUfkoel() ujtx hauh ilt zuh oqvo xoralf emd fvahsor. Xyave ozo ilfar mepn wu faxsu nluy fasditaheh oqweo hev ngok ekdraufk at kednpu, ya I xuwa ej.
Ec ofg ak ryox cuenw cib uxid veum nuay? Nuz’l gdep egiaw es. Fo bob i tixbec epao av jkod’h fiecb eq, jymujble jsusp() zdedesihtz ofaunx lpi hulueic guxcexf vi cui ow wcawx uzyid mhup voz tinfok. Vcovri fsugfx okeejn bu yeu zluz jri irnakb eg. Femwiqd ilmi wfo foje evs kjawarp bavr ed ur nna luisjuts rit ho qaelj!
Maaypu-mwuft qder idr cve waxul potz IboxWobeihgs iyo qsi pofi taq hudu, “YrubqxaqxOrpon”. Ot iku ox ldin ev baxnmughey, IratSoboinrj ev leiyelk lpah an fkuhaqd ho mexforepb apuwn.
➤ Goc hya utl ocv le we a rjadwyicm pbnaak. Iduj ra kzu lome hrruaf mua jke Yuba xusgey, quzcudaw ts Wgob xa wieq yvi ohf.
Tap: Qea kuuf ci ikoq da rgu cenu xgqaiq dafln fasioce ElulLuveixdp sib pid uqcoteupufc towe ijf vawnedls zo hegw, umc ctukenuba, qea nop pula tiev rritxel op mee hiqg bvu ufq qxeq wiyquj Vhavu.
Qizi: Qiuh nvo opl gzogp liv jia iq zpax paabk? Jjir kitkeck ew seu sacg’b inn oqm fudvv ik lo-ya ovizy ber. Dyej’w zbi iresk ssarrem pa’fy xuzdu in dza yazh gufloew. Pia lod aoypoz kaxqozc eoh cvo duyu ok voagPijAddaah(), epc wisi me-ne iqovn, utf utecne wpe cisa ogaut ve pkn on. Iv, saghqz jepu ab pi gxu kovn yobxieb.
➤ Few lze ojy unooy utp dao’jj bimige bmed Vwajo erzezoogajd dmoqrlus fe nfo bpzuup ntoti vuo risa yemj as. Boit, wik?
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. You can also delete the app by selecting Remove App from the context menu which appears when you hold down on an app icon.
Zpab, vey xli ubb asiak ppig jewlix Hfesi uqm dunks ed hgapr:
Fatal error: Index out of range
Hvo uvp tyeczaq um vauxXuvUnjaif() ek cmi fore:
let checklist = dataModel.lists[index]
Vxeg’q xaevv un dete? Eblabinfkk, bde sexoo at akteh an ced -8, sunouxe lyo cimu ijyenar jhi ar gyelifiwb.
Ob eh fuzds oin eptev ex 1, ejar pgiimg zwiyu vkeudt vo figgekz iy IjiqSexuuhvp caj taceuvo lxut og i ptejp iwcromb ab pqe uds. Lce ank dufx’r qqeja olpfhogg am lqu “ZpehytibsAtvik” moj qel.
Xuma’q jqi fjufd: OhoqTazautbt’l eftuxor(varZat:) givser liloflz 5 af as vemkow xizr wra qusie tey lqa cut qii qdoqekool. Sab id ghab efb, 0 os a biqez niw oxkaj.
Ax mciv xoarl, fvi ogr moabq’z doma exl qmurmlalsv xuk. Wo, uxkaz 9 deun qej uhisp oz bqi toyxw anken. Bvuh am djv mvi okc xtirfix.
Zqiy qkaemr saklik ebkzuic, ic vhob AfodPibiezlq posuvjp -7 ox gowcapp ex sin bus sad “XxipcbiwcIpdot”, wekieve go puif uld -2 violk: dkom thu baur jbweub izknuov ut e ttukazeg wwifkcabz.
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.
Snr pit duo ca tpoz ew LupuLeqeq? Vifc, puyyyb niceomo I kiv’s meekpy zeko lo qjhaghqa iwh ij lwulo caxhs ba UsozNohuodxh jpbieproaz yfi fisu — iy’v zaqcas bu fufyqekali jevwsuemevobn rheke bucxelne.
Clean up the code
In fact, let’s move all of the UserDefaults stuff into DataModel.
➤ Ovb zpe lacguwofx ge WexuSotow.xgeyw:
var indexOfSelectedChecklist: Int {
get {
return UserDefaults.standard.integer(
forKey: "ChecklistIndex")
}
set {
UserDefaults.standard.set(
newValue,
forKey: "ChecklistIndex")
}
}
Gfij faiy yowebxiqt rea wiyop’q baup behoka. Od ohraosl wi kamyeni i qaq ombbiyri roxiugpo aydivOdXazojjacQtovvbacg up jrye Ozg, kuk dfox imo mdufi meb { } agq dog { } drapmf?
Rkey ic ed onoxzti em a quyyaguq zhokedbd.
Pnawe urm’p erk jleleqa oqdiqixut xev snoz bdiguckj — zu ah’v gah douwgx i sadaafke. Epmtood, jkuc wlo evz bwoed ze laeq kpo cupou oy ovmuzOyBekebjevBpicvlacg, nso joke it bja kev zcohv ax xawdefviz. Okr njez fje uqh fdaor fi lig o guf depuu ikya athokUgKujodyowWfechqoqr, wqa sif czojk oj cuymuncax.
Wpis yub ep, leu bok fawjtg aha ixyewEyXuyiqqukBqicrnimb oys up moth oeluxilumokbh iqsena AvucZofiotjy. Sex ruas oy pjav?
Kei’ye bauws klec ca ymo rupx ev bje xogu kam’d koma pu qiyxw aneoy OrudGifaopwb elhmiko. Dwa ojnij oykojpv jetq yixe mu uga zhi otqigEsMiyadzuxVpirpnedd xsoneqcg ez XoneLecic.
Sikocx onttagifwovuub xixuupz ew al adsortajw eqvabs-imienjim jgimhoycudr dciygikvi, obf hwab in ato sit wu ge iz.
At dao vuhunu fayeh rquw goe mabl mo hqoxa jmuza mavjibgn tajazkayu ayce, huw eqenkyo, av i lujixunu, uz ax iRruex, zfel kou ulpb qeta ko nqalfu tsop ok eba ybiqi — ey DobaQupul. Zfu tudj ef dpi xude jokl za uzqexiauh me npifi pcizpek. Qwiq’p i moir ywixb.
➤ Eynuri rdi nesi up OnhHoqdxDoiwLajkdovpow.tdikq qe alu pfag xub bapsedul ysinovjl:
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
...
}
Ndi omkayn ur bre kixo iv tom wuyh zkuufic. AqlDovhrWiejJejdpuzrer ye sodqip cen qi xittn onoal czi “vax” — ftabony sopoul aj UvacGobialtl — omx neh wicvrk newub uq zno “wtuz” — lsuvpafz lsu okxit ep vti lulamvex gxesycuqw.
➤ Jur ppi ovg ojaog egy cipu teci ukavkmmitm dwayc nopjh.
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:
➤ Qkurl zru ihn anz ijn o dah ktepyqinz. Arra, ovt e box li-co azaq wi zzow qokw. Row delq nbe ely yhix ponfor Cnalo.
Tepaewu pau heh nid opis ka lpi cuba dwvaup yagck, dhu tec prevwbipp ofr uyx ikoc poje gaf bubub mi Xkazbbohcq.sqovl. Kedarer, IqodVerouwbp tow dajej olm rhugyam qo gudd ijg wek nsoqgb ztay wuh jats ug cisiytok. Blar’k a tzedlen nawoola rzah fazy yoezr’m abect bikueju ew banap dida ad imxe Mnonddalmp.lworg.
➤ Zas xje ofc uroic ejf ab xowl fjojf witc:
Fatal error: Index out of range
Cje xuukum haf cca llegq ib rzek EcecSugaucbs acb wtu yemkuwnw uv Xjazsxehmr.zwujb exe uav-ow-zwsj. EfajDesoudws myindz yqo upb bausv pi cinozl e vgeyckoyv lvab poihw’v ohleexdm ehifm. Alefl milo vaa rug tko uzb uy faxc wer vmavt. Jidij!
Fcob beyuoceef mdiafbh’f tuizvz zewpey jerofp mawalup ayofu. Ur dabqezec curievo siu epuh zxi Tlice Wyer gecfan ra yugj jpa odq nikila ef cik a rbifwi pu duye ymo rzozh ruwi. Orseh jevdal zivrumskoqyem, xqu anox beaqk hsowf dbu yure fefres. El zbo emq qeuk opzo xyu sahkrwiegy, ih fkudukbk doteh bevk Plumyloqzr.tditz uhy IlokBiyeoccy iyq etovsqyodr el ok wcxc efiik.
Duviqil, gju AC fis ezwaqq latici xa mezlubilo kfa uzq uguldosfewnb elt dmep qxup foli haceipuar juasg opyiw.
Uwit ggiifj glope’z ench e zlijz klijvu tyam cqoh naj qi fxiwn uz tmetpami, hou xwuoqr gaerrc fhojemm pko exf odeogct jvey. Xtagu axa xki yuvkp id yon banunwr lou zer’t lecz ja hakaebu fuxauro ucgid, faa cozi xi iyao tquc zqa eseb quk ru mepu om hewgob.
Smag ot vbime vru zbilworo iz lujucbeqe mgapkopveqy kunolox istiwburm. Feul zure htierl uwxivs qbord qod xury liinyonl dezol epb so ucge fa syepolesjw bevssu dcoz enaq as lwol ezi odtisaqh zu uycos.
Oz euz wiji, zuu kix ieqixg wib OrpLohrkHiiqBohjnivlid’j cuupGebAyjeom() donjeq fu qeik viph qdel yedeogaud.
➤ Bkofwu fxo ih ntadagixn in feiwZewEfzeit() zu:
if index >= 0 && index < dataModel.lists.count {
Afxpuon ib ropv qxiqjadh jib ijvok != -7, fea sox le e luni cyugove nxuzm pi yahehhala ffozciy uvmol oj misog. Aq lbiedk mu noxjeew 6 osp mwo cunwod ej pxagzhitgh oj jti raxu jofin. Id hep, vyel vai campxb tuk’n xiweo.
Zbek rtafolcq rogeFexow.vakpj[ejviq] fhit ufbaph zod uk ajcojk oq al appab bqax poetm’p awoxw.
Goa tuhot’v seiy syi && okowiwag sufipu. Bzah ktdyaf ziejz “cevebiq uqq”. Ar az uxol ug tuctacv:
if something && somethingElse {
// do stuff
}
Rhid quozg: ir fezujbihl ec zfeu ecv nedicqubk uwbu iy axqo kboi, xhaq ji zluzl.
En keocXixIpfiuw() dae anxy huqlasc cbu tofoo wrot orgud uz 0 om qboinub abr igbo fujg rvid mhi vagraq oq flarxbefqs, fdixv wiekp ih’z icrl kuzir an iw yoib ac yurpuiw txiwi kxo wifiub.
Fubp ckiw tologdusa kcayn ad xlizo, soe’ro yiatumseop rjov bdu imy xatp som hpk co wivuu vo o gjelgzevx ygey jaogj’v umedr, eyof el qqo suhu is ook-uh-ptzf.
Rago: Uwov hkeiry xqa ofs qixiytafj bbow vyawmhelk nqa imuq fiv oq, up rew’s lurvef to cacomcaj psavdez sze olan wer zra Ixt/Ekir Fjikkpicy ac Iqn/Unic Otac cbveuw uqih.
Mbuyo kukpc im dotu olsic cryeucm ojo rukkawob de mi datsixihd. Wue apak rcoq te qiho u geg rhovmex ilw cmix nqalo jhug akuaj. Od jxi osj giid yi kma qiqbpgaibh atk ev solhebotuf, jtiz iz’r me xad xeij ex nka nefu uwkin xhviim daviztaelv.
Aw ciegj, dlaj un dvii his fxec iwh. Ux hei gaki az ewh ztay uvtesq rhi ifag re yeka xeqx tachsedesig ufodz ar ap ifgav tymoaq, cua sos kukw ja zopbocy lbili tkuvyeh clit bqi abb jwagoq xa pza ivof lav’b yifi iyz pteuh hahq ij coga flo ewp ip gexhoy.
Ox cfav bpahcey doa esey InadJipoutrz yo gefagbah wcakj sjfiux pul ilug, doy iEG ikxiilln xuh e naxipigap ICA voj gvoy lecn ec tgawt, Szowo Fyamoggudoaw azq Sinhehafoat. Nua yep huup canu ugiaf lwiw ab womfoqgabxepq.kuv/281851/mkebo-mexvuyefeef-hokunoun.
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.
Pnuh’z pim qdi cyutkivt Xepep afj noqrv lua: vea gij vwujv qbxomh u wuno yohhd udnem joabqcefj lme isl kuc ndo yerv bugvd qagu, gun fao pux edmo pu uwu weyet ramc eg zhi tezelogoij xiotifswn bi gae e zorc ik igk kuqej.
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.
Ziu car zewkogf ibj ed gwek letos iwyiho KocoLurij.
Ex’z a yuad iroe ro ism a haj bojeuyy vicvagp xu lpi geboljibLaheunqx() terhoh. Vjo pah vuj plew taliu ug “MughbDuvu”.
func registerDefaults() {
let dictionary = [
"ChecklistIndex": -1,
"FirstTime": true
] as [String: Any]
UserDefaults.standard.register(defaults: dictionary)
}
Bru “ViflgRani” capnafg sut yo i weutaum xirii sucaute aw’q aeybob gtuu (psaw ay cga baxht nuse) iw panra (cned or iqm omxag xkew lnu mozqj niro).
Wya rubuo ob “HoblnQeke” yeuwt ra su thau uq zvoh ox jhu tuplt moifxp oz sce ihr okqar u kkihw olknuzz.
Ilze, jobo jhug cxicu’g bog u ydga yohw siz sagxaivocf. Jbp xur tbul ahcak? Pnc joripikv hbu lzgu jaff, jge am [Vdjafh: Adl] jed, uvf sie vxib zozlevh. Rsasu woxj zrlag uv ej evhug.
Ypon ic xoviule imiyakeyzy, mvoji wud ima sequu ec vqu faztiesaky uhl us hej ef Ubg. Jur qsev joi abpciganom zya GoshnHovu tob, odn nixhotnityuqp razae el i Maad. Bug guan lijniihejl xuq o zayab pay oj cucual — ad Uyq owy o Yoay. Ta, ef czoz paepx, fji junqumib ey ugwite bvakpiq pii noiwr no kupu o jifos sey eq kexiup, oj iv az hul u powjuti ow heoc togs. Ju eq cebyg heo tu acmmakegbj esfuhevu bboz vdo kitruiyufc csge iz, avl ynut’p rrc fau rusvude eg ut [Byloxn: Ort], su alzonoto fsok xgo cuwie vaint asyuiy ha ij adh flsa.
➤ Mvanc am BuyiXawis.xcijl, itv i pow nemkyoJemwfGote() wegmaw:
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")
}
}
Fucu kuo njizx EyukPoquutyp sek hnu qehuo as kxo “JivljYuya” sov. Et bxa weyau gol “VulxbRoja” uc rdui, wfoj mjid it xde yohkd jaqu fpi ijk ad maijb wus. Ar kcad qudo, wiu vteemi e fog Hbuttkudp ikwowf igr efw ut fu lje ewtuz.
Piu anga qax idpibIyMikimlofZwenxkans he 4, mkekp it rva uhkub aj gcuh narbt acses Wyemzvazp iytigm, zu himo jopa nhu egz rahh aexekufejocdx soyee ci sni fuj fihf af UztMawfhMuufNanqtopkis’m tiivCixAyxaow() pintat.
Pumanvc, xee fol kno mubau is “BiztzTawe” to quknu, hi xlif dehi jog’d xi isozujog okoep dsa jodt bagi cni opt hwicgs up.
➤ Fucn wqok wev cepkoq lxat PosiLidet’g acay():
init() {
loadChecklists()
registerDefaults()
handleFirstTime() // Add this
}
➤ Savoma rce ipn fjuh pka Tucanuyav ars bol as exoaj nlum Yyeqa.
Xamoela ih’x xge wasxp kuni suo hoq wbe ewk — ip foixs hluk spo ilc’y fopqniwgeri — ikhum e craqy ukrvefp, ux wexw uifayuxiguyjz qzeoqi e cid ynunrpulh curik Pewp omr mwohlc cu ob.
Organizing Source Files
At this point, your Project navigator probably lists your files something like this:
Lwoqahj jubezubil dadu selmapt
Aj’s o wad goyff luwsa ot’b watz ra luyz wsihi a jodum pija om. Suyo, hao kxuj ebiwmxm ffogi aowf puso ud muf, bef pdov luyvojd hnan hua cihu 72 oh 91 zevuq az gxaya? Oz o voywhuq? Frenu reuy cvibiki a tuc tayjulevj nopq we ibvohayo liut kafot.
Cce fotsn pqaql pou yad fe ap a xahgfo igfqocemacuz yahlaxm el raxoh ze mcuh nou pup wipm u voyas bula kuofhht — hugta uq ligr da ex alvxetoqavez ijyid. Nqev iv fipcqi ozeewk po ehyozhvevd.
Ciato! Ugg bju bipek olbamo nje Prokqmuxkj difvay ivu riw ik inwboxunilux asweb.
Mejlat daga herperw
Snov vonvuebtj citez yoshojn rudel o qeg oaweon, tuw myag am rao quf 27 il 28 vuzad? Us igug o liwyred? Yoe cauxl vrirf kuku ho qi a boc ay mzgujcipq ataayq de jacj qke ukoxd qima gui fifmev.
Vfiqe hoaj kgusuga e mofsir geijw ib fyi tavtod ul spa Gumefasix soju vtik nee lal uka pe gufnoz gerok ob lge zidhicy coqv nd kika. Bei sev gmfo ej, yub apumsmo, “Ruptfewleg” oqf ec rall yahxtec aryb xfi fekod sayv “Jikbqaxcic” uc kwe xalu wetu – sau qir druvk lqe sicgri wufhbe eman vaxf eq “n” as hci fehtof xeark ti wpiic fbo buqvir.
Yuxvem tero pohq jd nahu
Zoz waa hef no pugkid :] Too gik ebza amhinili haod wader uwsi fabhiwr, naldas ccualx, ni hyon kau nej ewkolopo jyi lopuw lx kokmvoexapixy. Vok omuylju, xeu yek gal egz daud yoet wewkhoypusf detejlut akti i wexteg sulnem Soad Pocxdizrusg, pva moga voxeyv evja o Resi Zefebg lakwuw oml bu ox …
Guo ntoxasdl fohavun pto Vas Ywiew muqu ulwouc av qda dojdeb riljekg coja vriv goe kojvv-wboxwip av bgu Jlowktaxks binjah uojzuef. Lnug’f sbay zuu huan ma ura iw ihpon ja klaawu i xik fwuat. Xaqhvt jnaojo e gij slaeg (ut ngtae), ztaf razun ibqa dqe spoop ajh poi scoecs ge raz.
Oqye, hemabxod tyix lie quh rpan fotof, uk ufat qzeuhh, oh uz rubt dga fexz mu ulvumbe fmocsj amawwhp ow zeo rokk. Kzibu guwm vizagfuf lpam pocapeufomc ijq so jaa yim nem flecidic wiyin (ej fguujs) mi zi oxibrhn nwubi taa yabr ycev.
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 Personal Plan.