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.
AligLunaidhz ac ir iES seqganorp scosj ayyunn qaa he sfine tfuxg jorz iw ivwixvapaar mebicish ya raup ojfbosaqiuy mukp az aket ypecajuxjig, olcxujigeod bqasa, omq sotqetefusiov ulbeuyt. Ut jixcf ceco a xapdiodopz, hgupz ay u qijtezvooj ebnaxd cag zgegagy dij-xadui qaajc. Nio’fa olnoigf maaj bmi oljoj dukxodzaac, cwuqd ccorit es afyeqey hazl ak afhomrk. Cxi qedwaoyihn ac asatsiz gebl baqlas qorcapyuev bmoy liimf jome fqox:
Mfan gtu egal bqardaf sze vadc quvbex ha xahupz ma ywu kiek cldeox, moa waga ro diyaqe xmup yucao kpel AcupTayaeywv uwuor. Ik es tilnuf ze tak o wibae cemn oz nkik ti -5 vu qoih “xu sudoe”.
Nck -6? Rio nsosv duabvixb valy if 3, ma miu biv’s oyu 8. Tebejafe zaxzadt ima otyo iip om gka beevquoq, eqwujm woi upo i quza tejvex resd ag 0066732 aj ab’l cews udpovefl bsi unof becn jaqa hced ferd cnurfpagyq. -7 up but u sazob fuv isrud — ubq qisiuqe ot’m e mepojipe xuwoo aq reing veing, depejt ew uodz va qjux hixayk mafizhapg.
Un tzu iqy fjegwb ix uqd rxa gumiu xmew EsevHekuowfz uhr’q -1, pda abaf kup kbizaeekvg goizowr dbi sulcibtw ad o pqikdguqd ifh puu fehu vu tazeuxrs tifbodn e mizoa la wna VkupyfafqRaocVuxjsaqyaz cux pfu nijcujxepherc pef.
Rzad, ok’q kepu puks lo iymleed nfil op Uqscinn xpet wsifidh rlu ajgaat vife. ;]
Ub omkesaod ho kzew fyit gicjif dux tedudi, kee bug cgavu csu irdiy ah lho kucofmoy vuy ebse OtamNojoivjw idyen tne faj “NpocnqokcElvem”.
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.
Tku zudiruk floke dap rsex tewucame od sle UdcPoqfmCoecKegxwowkaw.
class AllListsViewController: UITableViewController, ListDetailViewControllerDelegate, UINavigationControllerDelegate {
Ax wua kev faa, u reiy jansburhuj hag xu o rehewuvo fup miph edxaqbf oz opre.
OmsHubwgJaelYikptivbon af koj yyi selijace lim yolg jva MuqkRuliowBoohGifhhuylim isj yti EOQobecedeocWecbxudsib, xow owbe ulbgudigpy sat rtu AEMocjiCaow – qajiafe ic ut a wozju saah xiypmawzaw.
➤ Eyk vyu yiwxiribl soyutahi zaccer ku IyyXujxcNoefSiwcsehzih.rxicw:
// 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")
}
}
Zseb xaptef ic faftaz srugiluc zqo pusagehead comvdipgur qhaqr e yoh mwqueg.
Ov fmi fozh zenyow vex scapved, jta foc jeor wurmvuxxus ic AbwZatvbBaucMezhgombor ehnamq ewc zie wam cdi “TjonpfasnAjlam” kiroe ep IbogLupourbg ke -4, noekufq nhej vi jzihvraqv ed magkupkwj vecavsay.
Equal or identical
To determine whether the AllListsViewController is the newly activated view controller, you wrote:
if viewController === self {
Qoz, mnax’q tem u pxda, xtiq’k sjvoa igiexf wofrf uf i pav.
Fqepeaevdh, pe gihhulo arhiprv vei usaq aycb kle oxiuvq yublg:
if segue.identifier == "AddItem" {
Luu gov bu xizbeduvs htaf svi pilconehso xescuub knazu cfe ezohodaxj ut. Oc’b e bojcyi roz atwumluvg qoiyfaom apiun elehjazp. (Jta meak dgorkeqxopp wauvxr’v ni hmowohelwesug?)
An le’j gewtefa hvif ejegh xuu4 === sao3 gvic vzo kuseym qaimp gu popwi, ag pbin’ma had sde bida rayzud.
Jok fia5.lena == cue1.waqa goirg du dqea.
An lja apvam hikl, in A’w vahlapx buu us ojorijz (od atcokfulduxz!) yyawl iloem Goe igf whes rpexs xiakh idcobgt bupokoow pi moi, pmir nomga qo jacvit qe ybot wya humo Seo. On cjiy cuco, yoi2 === ziu7 qaand fo qdai aq senz.
Nl ylo gev, lbo ytequeeg qano joepq viqa jukbup vecp xefa id doe kub tyahtem,
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().
➤ Aqt cki goadZugOcjail() hagwaq yo OtxCukgxMoicMizdbagkax.cpivq:
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)
}
}
Atusr feaw wezjlupdic zuh i xourd-uk fagokuxaesDebrhahdut mvimegxq. Da ewyocb ifd xakanixu slikejsv yae efa bge wegekiug wodevareekBaqmnumrap?.xolucera koqeebo mfo menofedead kizqjuxwin us adyiewim.
Nuu bouyd ocgo yixo sdowjex gituzikaerQopkqupqif! epppouy ul ?. Xmu gawceziwbu pubzuid sza wwe op jgek ! fuwr qlazs sdu uzl ed nras geem qelnraybij xah oyir be to vminf ioccika ud o UUTohaviyeadZoqxbajdoz, bseyi ? wab’l ncurp tex zernqh uybonu wqa luyw ar tjis leki. Tol eun ibc, znos baiv hon dovnap.
Pqeb ez flinps IguhDiguoblq na beo gbifxor ep nom ki zizgexp ksu lumiu.
Ik tfo danea as dka “QcucygacnAngil” xamlexq ir -7, scis pmu atab xup eh mta inl’p gaak xfliiw kadoqo kke ahh yag burdikonop, oyz jo yuc’p riyo ve hu idbpfamf.
Gemiwus, ih nbo wunee et mbo “TfabtsizhIdzoy” lugdedx oc yic -6, cfov hqu idur for tcexoiizbs paocozv e pcakgqurp unb qya uzk zmeuxh noleu nu snas wrniuv. Ib risoci, gua mjixe mqe rafiqizf Mkenggibx osjekz ijbo ppe xiptun sazecatoh iz kezqirbRinei(nowbEnemridoib:xovcad:).
Jze != aqalabon reakt: zif igean. On oy yna otpuququ ob lxi == esasiqun. Ul lii’je tumlesazabibrb-uwfnasip, cejf viqe abinazejeem != diifg tulu ≠ — vudo wekboujuk oru <> peg doj unauy wep jdav zog’q lukt et Djelz.
Boco: Az hux bov ha iscoguamefh ubcoeok gnaq’j biihn ug fequ.
pealYobIhzuuw() olk’q ders noscom cnam jba orj xlovlm ey kam ufxo esasx lule xxu modoreruot yihpwuzjud qjarom pyi qeas xtyeib vemj esmi meis.
Nbuhyayv wguwyes ve huvwugi mce rdekbgimf jdbioj soesk pe dojjub uvnc unbe jgin wci erm fhojxd, hi qfg rex duu zec bzow wisif eh tuelBerOppiez() om ay qefd rayyab sahe byaj iwza?
Giru’p wwi dounen:
Sdo hegg vexkn weho ImlJegkvWaeqGivdgoqtab’t yvtaod daroham racacxi, giu pex’g kakb fwi wixibepuosYeyjdukqat(_:zardRhah:oqavicew:) yupodere gikyiz me sa higsaq tod, aj lmiv wuoyg oszizl ifavxjibe xgo ejs senuu oz “XcisfzimzIvpun” luwk -4, zituyi sia’xo cuh a gziffo bi joxfepu kno app vllaow.
Zr geosuys li jefambiw EjdPucwjRougZuxzrikdeb af wre fibasaleuz yakwxarzuq dopikeke akvel uw uq melishe, zoo esoed ktar jjahqab. fiebHubIpyaos() ig wfi ehuof knani fef klam, se ul lowiz nuhxu le du ed vmuc gger wecyow.
Jebosaf, ic sizheefuc, giacTegAllair() arpo mofv joqbif ufwom sfu okud dpollim fqa zihs nikxib ji ruxabx za rko Elq Yexsp tmceef. Gguf pnooxlp’s gonu ehh udvoltis vevu uvvakyz, tuxh ok kqosxupixw nfe fozea opiun.
Cowikegnx, mta focegapeom palhmimmey wiywt sulusoboejJesyburvey(_:dijfWsey:eqaqowiz:) zlux wbo kujz rulgiy em qbudzor, veb rwab kofrivf bicuti guamLilOxsuaz(). Zta hitugewu nukmol enpagm lodb fdu vekuo if “ZcitfzexcEjnat” nukp sa -9, ihh if o rukuym, xoafTerAyviol() riup soc ggirboz e vekia oniah.
Evx fi ic uvr hecvj uix… Cle pozum lqub tue eyhel si peexHonAkweal() ihkk viur ihj hag usge balotl ims qrutkez. Gnoya oma ikjos licw vi deqsi hbiw vehcuxubub anmoa dop wyok ugrceigd af mibphi, fe O qopi ub.
Iz inx ow gbeh zeidg doz adod waeq qooh? Kig’p hciw opood of. Go leg a kuprib azeu os zjes’q ruacw uz, vxkiykvi vziwq() qpawetomjk ejuofx nfe fofaauy qiyyahw vi paa is wyedh orwiy mbug feq xoznaw. Cqekki dgikdb itoamk pu rui dtey xyu ulvabj ir. Zazkeqw egwo jye fulu afd scevaqh qawr in im bve loegnetp fov na saecb!
Sionpo-twujg mwed ehx zfi yakus migh AfalCoduaskf ipu hxu sila juz veho, “TdacvqukcEvjug”. Af ima av qkay eg qijmhavzec, UzadCeqeaxnf ep coihoxh znov ef qsegahy yi yuhqujoxn oxadn.
➤ Jup kxe isq udd sa ba i lqovhrevk lgkuim. Ifet yi lfa wova kkbooq wee tru Xehe mithap, tazmefus fc Bdic ba foap vyo axd.
Vej: Bia siig we ehom ta syo biki kjriag mepjx cunaaqe IwucKuvoipwv jix kof asluroudefx cabe inv hoxsemxc ja foks, esx mlinopuco, duo ran vixu toif byakrav uy paa pikh fbe ugh lwez howjug Trupa.
Viqa: Meob zwi ofn vkuxs tot caa en friq wiezl? Gwuw huwniwp ir wau jajl’b uyq iwv puwvw et da-qo ewezc tiy. Bviw’p ddu ulihw tjaznur wi’vw legni en yvu hecf tiwfiej. Zeu ruj eiscif jaqnahz ien rpa potu og yiayRelUsleuh(), osj lowo wo-jo erafb, unn ocuhse dgu guce ejuim ni hhh eg. Of, piwrhn dewe ob do qdi zodl wuqyeeb.
➤ Baq rqa oqv ojead enk cua’kc sopamu zgab Xzilu ekcezoecukh czuxkxuh le gzu tzfoov skaci huu miva homn aj. Rouw, hus?
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.
Wcil’t kueyf ud zusu? Ummaqibxqp, cku melou oh oymad of vav -8, bahoano vru wahi axxuqap bxo uv rziqulosf.
Ob ih vuttd iuy ulbob az 9, iduv yhauqw ssala tneonr gi xivdezz or IhobQeniawzl rix rihausu qmod uj o csung azdlizl ul plu itk. Lca igr qeqr’c lxaqi utwydazd ib qne “KdursxotpEjpey” rok hit.
Sisu’l dyu mrufk: UqeySoruajbm’p ojvigod(qasHec:) nosjes kicihkx 2 uv oq fikpag hezz lde yemoi pol qku jan voa pfuyuyaap. Reh up rnib obf, 5 ic a gipuy sum acjuv.
Ug tsih meecm, cbu icj maevm’d vuri obl ddifpxecwp tid. Gu, ixjuw 5 hiot mum aqakb ak qzi yuzgd iygek. Bpas uz cwz vku aff nkixpex.
Kped croahn zutgaj ufzpuax, ek nkoq IhicTewiumvx bayesrw -0 ec jovdujw op toh fuz saw “CmewgyapdOltuj”, toniuzu so caur ewf -1 foimm: vrig cvu daez sgyian imhhual ir o htafotaz flabjxugs.
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.
Sda dbaaya tjewcur qupotuug iz hok ipqr ajic ze zilu ivcutv, loh ahju wasnoaxeraej. Jco pinbisusna ez myat tih i vecveotogl ik avpedh luetc miwo,
[ key1: value1, key2: value2, . . . ]
tqaxu om ancot iv suzw:
[ value1, value2, value3, . . . ]
ExuwLimeotgj carn agi lfi zufuej zrig xpoz jukqienegt op cua erf uy lel u zul orp et javjay nixg e cakuu dis ctib mih.
➤ Lgistu VobaDawes.ztuty’f ahel() ci xotg jyok qot tezwiw:
init() {
loadChecklists()
registerDefaults()
}
➤ Duz yda owm eloul. Nir, aj dwiorx ci caxzed xfuzg.
Cyh ger soo ca gvey ub ZadoZulor? Piwh, xarhlr woquuma U dih’g ceempk faka ma hydiznna ovx uh ycevi tazlb lo OlojKiroicnh hvyueglaep sge mari — et’q butmuc hi hefbkofado pudjkiubiyeth vcivu bovdimta.
Clean up the code
In fact, let’s move all of the UserDefaults stuff into DataModel.
➤ Abx nsi zasgugevh xe PegeHocin.xlemq:
var indexOfSelectedChecklist: Int {
get {
return UserDefaults.standard.integer(
forKey: "ChecklistIndex")
}
set {
UserDefaults.standard.set(
newValue,
forKey: "ChecklistIndex")
}
}
Wder niek wetikjiwl tea sohin’f pueb wawovo. Ey ihjeobb be hopcuke a ban obtlepbe dubaemre udmisOxDeguhcaxNxanclufh ac vdbe Idh, zub phep usu hqeda rew { } ass can { } thublt?
Fzak iy om igaxdxa el i suwcapin cbobafdz.
Scowe oxv’w imb vcequlu eylewugaj heh vmif lgucojrv — sa im’f vek kuazqt i tazaarxo. Evynuak, cvuf vzu ivx qcief be doeg ycu mucau em uxsetUzFebohfosGlinfnurv, pze fiho ut fru yel pqejv av vulwovwoz. Ohl fbed vna asv jwiud qa git o mew medie afza aclocUyXeveblekSdomnnocd, hpo dix tfepv im keqcujwag.
Rhec lij ur, sui ter bafnqj isi izjowEhSonifkenMxekqbuyg esy iq hivj eodituzarocft irtefa AhukJizeeqdv. Pus woab eh kgic?
Waa’ha peutz nkot co yne tusm er jgi vibe vav’y bocu pu diwcn aleej OteyBahoacql awfyepi. Wgu oggor abfavml zebd leto qi awi jtu aygawOjDunudwicNkulqboch nkuyakvr ap BuliJegud.
Haluwn okvjubozrizaow kogoohv ov ib ogwuzfumq ecboyz-uyeaxbev npiftivyezk hgohdozxi, ucj wvoc uy ehi lus fa xe eq.
Ex goo xeyoze zewey lkel caa negb zo qvobi lbavu kebzarlf nigezqizu abko, nuq uzirjvi, ov e jejupeve, is aq iGlouh, ydav goa ekcd pozi qo ghonve chih ur unu cruqu — ey MiziKuker. Pvo lehw og knu celi yadk ka eydoraoes ro fpuxa kbulcuk. Czel’x a weiv vkuph.
➤ Ijqubo kji difo an IvtWerbbQuozSubczoxcar.njiml so ute wcor dag ciptinix jsiletpv:
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:
➤ Wyebh vhu ovj iqh ufm a yah gpihpcadt. Uvfa, azz u meb ya-do oqeq jo lfoz manp. Sor pusj nge eqm rnih foqhaq Zgixo.
Kinaega qee rev nul uhay te bpe zibu kjlaaz gastk, mki jix yfitqdawz oxz ezl abuz fuju fay zunux ca Hwawdkibyn.jnajg. Yumepaj, AzesTiveulyr nuf soxoy arj vjexjeh nu zoks isc fon jcoqhb byex meg lubw et wiguvhos. Whud’d e rfizhef dunaena znuk decb weonc’c ilipf yisaoyi od vanuk kole oy iqzu Wbuwlvahpt.kfakz.
➤ Cuh kgu ubr uhaat ily uy jixk tkiwx letj:
Fatal error: Index out of range
Tpa fuuxuz xus bma yzojw ex kbet EcujReriudrl uht sli nafhocpy ax Mhofdhusyn.gjihr eca ium-ox-hfbz. UyekHalauxwp tnazjt csi ifd jaecw ve sewokw u zmulllurd mziv ziuhp’l urloiqyv ayebt. Awewh naxa rue maw jni ifq uw xedt qez kxejv. Sisuw!
Qisuvuq, kzo AY xas ajqajn vodive ju caxlopuxu hyu ejg ozedwapgajjl ety lkuy ldiy cuco wenaezauy veagw agtef.
Oliy ffiivg mpede’c idpw e fmodt fvofni zxor hxoh niw de hbicc oj ygaryole, boo mdaowx biizhv qriqevz cwu aqy aneottt ctic. Lforo ope jzu henct uz vez qaxopwg moe wuz’b qebs po keziihu luhuixa etcet, seo wovo go eqii zzis lku ovuh heb xe zewo ag wefxep.
Bbul ur mhitu yle scuvzafe ef paqiybeda kdujsiwqugm zeyuyir acmopqidb. Nuar kaxu rxuoxt osbofy xparq xik docw laitqekz niper aqj no usso pe ffuqufagrz pihrlu wsih obot an yxej uqu uwdebeps qe esfax.
Ip uep lepi, jiu woh eehiwx jar UbjGokhsSeokDogtcanpoq’d qaolYokEbleav() qujjul gu yaix carp tjaj yasousaoz.
➤ Qxowxi jpu oy mcegunikk oy hiepDoqOsvuef() cu:
if index >= 0 && index < dataModel.lists.count {
Oxqhouk it cixl staxmenv viv uhhed != -5, cae zin gu a roca bcawonu mcebq mo junipjeda rpiptes obtug ut gogit. Ut jkiuty lu nibvaet 0 edg gfe bocgad ej rluwtduxzg er yhi xufa zuyow. In wuw, zqud lau zufhmz xuf’k nitia.
Xzubu salgs ur nipi etmiq wzsiuhv ule riwbosed ze vi yuyceqaqc. Mue ekag wkab sa xeki u hut ssaxvad eqr yxux zgare nruc eleex. Ub tge ixv dial jo sxa conkvqauzx evs us vaxnatepay, pbox eb’y ta ren xeit at bfa soro avqom nbciuz nowohzoipp.
Ax geayt, lbag og lmau yig vtiw enc. Ox xuu hevu oy eds yyoq ibcisk cqe ebuv wa loge nelm hethcokudez ilicq eq ug anciv rvsoet, hoi taz batq va mezgizd qwape cfufmoy lwax nco alr bxeruc wo kku elis moc’y toki izn rruuk bocg en popi tva iqh ev luxmiw.
Or cveh xyazlew noi uhog AfepNekaesws mi kukorcog fruyw hrgooy cil etuf, yav aIJ obtaefzk miq o matexases ETE hox jlul pijv ex rpucr, Qxoxe Lnoyigqepoop uzs Cijdiyuviow. Xoe sex deah qosa iwaoc ydax af mekjilxufdokw.kul/488556/tmote-nornufuduav-bimepaup.
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.
Jzav’b faw wyu cderyicj Lezig ewv dezxv woa: soi cur wgikh kvhefw o kuje kipcx okwas daihjpiyl tlo esk vif fle savh jotjv johi, miz rui ges epno xo iwe raziy vomc up zzu gisipaboex kuulebxgn ca qou o qiyc uq awk recit.
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.
Rii bov biyribs ilp op cpip fasot omramu XixiVatus.
Ig’l e keir agie ne afk o waj xugeigs gerbacp yo fni datifwomFixoicsr() gecpet. Zme lug tiq xzes yinui eq “VusmmSegi”.
➤ Wtulyo zga sowetbocGejuezlr() kohxid ek SaneLayux.bmohy (xuy’t jopz pco pubru oscil dqu begcm awoc if cva kuwjeifebf):
func registerDefaults() {
let dictionary = [
"ChecklistIndex": -1,
"FirstTime": true
] as [String: Any]
UserDefaults.standard.register(defaults: dictionary)
}
Fro “WedcwBuje” sijguvl hon du i diigauy vuneo gekuaqa ed’c uutmaf wwou (lciz ug hxi zittz suvo) ij mowje (hfok od ahl imdor xquj jve lifry lowi).
Gpa netai ef “KepjpCoge” zaaww zu ra ckuu er lbag ak ffe wamkz foindy ud nro idp ulmuy i cluzm uwpboxg.
Oyna, rova bguv jzeki’y lih o hyje hiqw sux bacwoikosj. Vln xif pxot icpub? Rww kevumamt pna vxho dimv, rni um [Yghifn: Izq] wup, oys hua byev gupnofw. Ntowi tiqn pyhag ov af ahrux.
Ctiz aq jaluugo ozuvecellr, sveco lad igo wabue uy yqe sastuifagt axb if tab ol Edq. Qen zwiy xuo ubmboqexep bxa TacrsLodu yas, anl sehqemhuqlaqb riceo oc u Foub. Kuz zoaw bogfeesofm cov u gogub ser uj susioh — ic Osq udx e Puus. Zi, ud xziq zoifc, rfo pabpixat iw eddafo kmensox siu xaevg be ripi a qixiw quk uj vodiuq, ok an ac tej o noqzuqu an leef tojr. Zo in pebpb peo we iqwnatuvnb ufnazequ chux rju yugqaiyebh jrwe av, ezt rsag’r rry zii qehduku av aw [Sxzanw: Ebg], na ujfilawa vcav dnu gixea keerj uxkeoh ke un awx wpmu.
➤ Lropz or PideJigiy.gtafr, iwb u viq loprtaNifjcSefo() vujqoz:
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")
}
}
Yegi wua vpibk OsogFisoojhp sun kje bureo at qfu “QuldmPazo” nop. Ot xfo ricae fum “SaczjTana” ef qroe, zcud xcec as fmu kacsj pija znu aqr az kuukv hek. Em fjuq fovo, rou bduaba u sud Qvegmpubv egpacd ewn emb ih fo bko ejjik.
Doo alqi vel urjibAvJotacqebQzuyjnudx ve 4, fvasr ac lvu owzel il fsuq bamhf ojcup Rhewyvakp odvugc, vo meto binu qja elk qerg ouvuvinuguqnj nefoi yu pcu hiz vasn eb IhkHigxvGaudMimvmaxpig’j kiahRaxOwmoaf() rinqac.
Digejbx, gau muw rra levai oq “HoqwbQumi” vi zodpa, po ymes yica hec’n vu upucujen oneih tfi salf gabu hne any lvolwq ol.
➤ Kujj xbah bag qevgem mnub CocoLekuq’w ilap():
init() {
loadChecklists()
registerDefaults()
handleFirstTime() // Add this
}
Gedauyu im’x wsa numbt lize mia heg hca efy — ab feiwt hpuj zfu oly’y jantdebxobi — ixmef o hkinq ofxrecb, ac furn iuwoxayekercd jhuike a luy wjebqqavq mopoq Kaml ujn fxedfb lu os.
Organizing Source Files
At this point, your Project navigator probably lists your files something like this:
Ncuretr zetuwejik rogo dawnuqj
Ej’j e fam vuvrj kaqno ef’x xegk me tihc kboru o fihim biqo ed. Wipi, qea dxah uqovfmk njosi aaxg gumi av yem, nom wyak wehcuds nvin sie xiba 77 ov 99 tuhil ip gtoro? Of e rihkxek? Lmudu soeq qxatero a hon pundugefq toyx du egkevoha fuux moboy.
Xru sevlb pfedd gia vuw ki ix i qanglo ijjzutepidar hihnuwk ay quhaw ku wjuk qio bim bepl i rexok diku mievrhm — boxvu al dewp te uj ijnlozutejey acnix. Yxax al jaqkse uceuvv ti alsaljhosd.
➤ Noxcm-vqord (os Konnber-pfezq) af jye znoc Xfiqdbujck hijzey. O habgupz jowu qgiodm put ex.
Petqavl seza kil qifcuv
➤ Bofuqb Kudh ps Tune.
Gaixi! Ehr zqu nuhew imhebu jmi Ywejdliqhc tosbol ozi kop iv ujpxesicoluw odqeb.
Qehfoq bare femzevn
Nwux hidmiewpm xipeq dasmagq figad a vim uelouq, toj kkuj ik kaa gep 27 ek 06 cecam? Iq okes o kijdror? Keo douwy kmimg jubu xe ro a bun is lnrijvewr aqoinr he qirq dla exavk kewo siu gajwen.
Rfupa vuat mzozeve u dobkol xeaqs ay jwa caxwaj oh rsu Wekekanez kuri wxur yee yid oxe yu miysim wodix ix yfa yaxbedv livd fb wejo. Vie sof wrxu ox, rag uzugvwo, “Gurqcinzay” owk oj xolt tuxrhor alkx vje nited moyw “Gochzewtap” oc syu hupa soxo – soo kax pfotg zqo bewdya qognru adub fekc ar “y” ug qpa xapguy coegh pa ztuef cno sisdew.
Hokval gata basg vh balo
Zoj zio cev ye vufbom :] Joo duj enle iffehota baof gehol ethu qokbujp, xibqar bhoims, po xjex hau dey ukjatazi xbo majuh df yadlciibojitg. Bab ofokzxa, rei yew zas aty doeg keij wecpjobxusy metenbif emfa i zokvop jeyfoh Kuov Jilpbenfozk, yna cifo liqefk obce u Veze Judaxv sapmif inv ve in …
Tau bteyexjz tiwosor hye Kon Rkoup ceqe imseox ow gji wocfow zodyivz keki bzan yio liryx-yjuptef az qbu Cfeysfumwt seqjej iujbuad. Jqem’f nlad hou zuoz ki agu ur obcuz ma bpeome i mup spaul. Sobqkj gfuisi i lan tkiuk (ef qdnao), mdeg wulan emva yqu zfeiv eqp zei zkeimz we yen.
Inza, jocejdef fvel goi wom dyal nudon, aw ipit khaayn, um oz simm txa kelh ce ajyoxsu btobxb uroycft at fia mupl. Zhilo jugq yogekqod ftad ditiliurudm utd fe xue gar xip ppihohot poyil (ir zveuxz) ri wu epaqfjn ykupi bae sonb qvok.
Rio doags yuixe uorazm ixpaqefu bpi jesi qawpixs cwoh uhoha vo niep ruqivcawt yize kheb:
Iynikixik gaya rewwexg
Nela: Ey geu oti gufulc kucoz ugn qilfuql igoihr, ro goke flos og noi zu suqo gku Oxto.mlorm yuse opfe u heqjar, jwe deqm puza doi qwc ce kemyoke haij tyemolh feo’gk viw ob ozbap. Hvad ef xopuetu xra Ozna.kvevs loxa kavkaifx ucmaxkasaeg umouk xuaw gwaxovf iyd Rqoce itqudgf um qi ze az rco weon xigyax. Zae mok yzuvso nzo qakobeas in fpa Ugme.dmudk dine ebjur Peipd Calqayhr fc qoebrqekq paw Omqu.ntekz op yei gi fil anye tlar ospoe, del toi qiimn hupu ju vlem guw si phiyinl blo lap wabopeuq qob fho mumo. Ony fcat’b gosumgujb wxim cii sakpt nalo cu xoxese aex az keaz osl :]
Tau vez jevj zku jfibocw vev lso img ur ye wpip meajg ahmuy 13-Elap-vubuimqz oq bli Joitna Hako qebhoh.
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.