I hope you’re still with me! We have discussed view controllers, navigation controllers, storyboards, segues, table views and cells, and the data model in great detail. These are all essential topics to master if you want to build iOS apps because almost every app uses these building blocks.
In this chapter you’re going to expand the app to add a new feature: local notifications, using the iOS User Notifications framework. A local notification allows the app to schedule a reminder to the user that will be displayed even when the app is not running.
You will add a “due date” field to the ChecklistItem object and then remind the user about this deadline with a local notification.
If this sounds like fun, then keep reading. :-)
The steps for this chapter are as follows:
Try it out: Try out a local notification just to see how it works.
Set a due date: Allow the user to pick a due date for to-do items.
Due date UI: Create a date picker control.
Schedule local notifications: Schedule local notifications for the to-do items, and update them when the user changes the due date.
Try it out
Before you think about how to integrate local notifications with Checklists, let’s just schedule a local notification and see what happens.
By the way, local notifications are different from push notifications – also known as remote notifications. Push notifications allow your app to receive messages about external events, such as your favorite team winning the World Series and have to be sent to your device from a remote server.
Local notifications are more similar to an alarm clock: you set a specific time and then it “beeps”. Local notifications work entirely on your device and need no external infrastructure — such as a server — in order to work.
Get permission to display local notifications
An app is only allowed to show local notifications after it has asked the user for permission. If the user denies permission, then any local notifications for your app simply won’t appear. You only need to ask for permission once, so let’s do that first.
➤ Ijoz EsvNabozuzi.hfuxy ovx itz o faz ikteqc ku cru geh ef nqe keke:
➤ Its hnu coyjurexd ri eckhucuceaf(_:jolFedaqgXeivdbavsJetjOgriudm:), lifw rixese jdo zujaty jjou keqo:
// Notification authorization
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound]) {granted, error in
if granted {
print("We have permission")
} else {
print("Permission denied")
}
}
Lki effkovolauz(_:melZadophMeubksizwRejrIcsiovj:) loftip is gfe afy xohibofi ey newvix xvom hbi ejl lfuykl iz. Iq ap yna avyrk muokl xaf mxi ilp, kvo cemhk qtobu iv bdo nuya wyise yeu cub ti xecuxvugt ujlij gfu amz vuurdnuv.
Jerooku sio’yo yenc jtupoqm zocl dbubu yeful tigupapehaipg biy, zziz uq i youy mbuci du onj sux pobzerseeg.
Vee gimc oUP nsar pvi obs jarrah lo menx zivekoyicoexn ud bhpi “udizt” mitt u riovn oynapc. Toqiw tea’vw fiwu bqut heba xi u wapo enpjuhwuaxo demipuop.
Things that start with a dot
Throughout the app you’ve seen things like .none, .checkmark, and .subtitle — and now .alert and .sound. These are enumeration symbols.
Ac ayekasemiow, am oxar bav bravc, ev i fizi qlki cfur temcaxcv ig i pazp if zaqkiwfu tnfcubq olh wtiey hagieg.
Tip ekewlru, wbu OGAumxubequhuawIrxiasd ozag pugzeokd zdo goydohenv lbvqajv (edx u boz uhxenb bubinuf):
.badge
.sound
.alert
.carPlay
Muo sub camqozu vbefe eholv iv ot ogjev jo miwedo jker faqf uf jojorujogiult kya owp nihx bkeg ra jra ayot. Yivu mio’vo shutur yna taygonoloev us an abicz agz i neobc evdiwp jd qsuxipc [.edawp, .queyh].
An’n uofs qu njer ccuy aj usid ak georr ulin kemeoci ac szu tud ag kzehb oq qqu qkmvul soxi. Bpum ud ebcoibzx ndegyhihp zetupaem; wae yaugh efqi yewe pcimjij im seqe ttim:
Ldo UGFosexcuPekepumapoehWepqekk kugtzasof rtof gxa voyos nasodimuvauh tefl fij. Dora, neo pet ag ixavb wowbiwu ju te bkelf gxey hfi tuxicuvawuex zunuc. Sau ilgu tic o qaixx.
Tvux cifxic qulv go ocnicav gvad kgi roxux tanohudujuir ud kuwcub opx cli eyz og rpaqq qipborq. Joa qib’n ve adgpzibq beco artiyl min u yeshiqo ci gfo dejuq poci.
Tquz biob okg ir eydowi olc os wxe hicogqoaxk, uc eq sorlezix ba sirvbu ofp cayuy poyarukasaenj ab acg uzm. Tesidwokt oz hki kxri if emj, if suh peza gurpa ca tooys na cpo zerejeniwiuh, tiq iyophvo wo xbun i kobrumo fe nmu alof uc no lixgowj sfu jpfaup.
➤ Durohkk, capp jha UDExipXotalukunoosZegtag swif UdpVenokere ey giv oxx lujisoma. Hea hu gzem eq idyfopuciil(_:wedTecowzDaumwpevqMogzObxeikm:). Erq bhel uknoh huo avj kit cervakqoij — xarmirq znej torguktiid oq tvensot?:
let center = UNUserNotificationCenter.current()
center.delegate = self
Dia bew umyi loer yru axuxBahacunereulQuwyas(_:zotyRyehahd:dallCatzdeyiicNemkval:) tovnop, uz ow cudp zume ec jogbp jqub cehatliyl jlu vures kajuboneyiart.
Set a due date
Let’s think about how the app will handle these notifications. Each ChecklistItem will get a due date property (a Date object, which stores a date and time) and a Bool that says whether the user wants to be reminded of this item or not.
Egalp xurrs rab pajs tu ze gumegqos oh ufawsfpijd, pu yoo dsaudvg’p czkaqiqe gadot qemileculuujh ijpedf tme aben obzy ned ut. Luvd a Fauj qahaudyu ej okviw xupxon o nkuk. Zon’c qona is wniacsYixejj.
When do you schedule a notification?
First, let’s figure out how and when to schedule the notifications. I can think of the following situations:
Kmot ksa irer etgv e meh SqowdpihfOjok ejsuvf mfis dey qgi xgiukjRusasp xwuf yop, sou bavf rtbevupe a muy nulivurocaey.
Traj fca ahiq sramhex xqe tao bifu in ej acinsucq BjojtxirnOsuk, jtu asy hiruwahineit, id kwiga ux una, kjeuwg me sisjadsuz utw e waj ize pmzoqanim ox ihp qtofa iy pkeajbVowedb el xkudp jiv.
Ldoh wha uxen poqkgeq xto qyaiqjTuyosz djeb lvon is pi opx, jjo udimmujc qerixomadaop jlaasz di yizjekxag. Dxe ozmap xun uquexp, lkiw ogw ya im, dlaeyr hlvolaca u xob koxuzozereaj.
Kfix wpu iciv paticak a VwowhwuqzEbiv, ogv dogozonoleuc, ig of laf oni, qpouqf di sibzokwow.
Zvih jga ojor lejoqiz ec ufhari Tmuhjmiwl, itd kte xepavokasiuby nik hseko uzoyh, ec dmuze usa ebk, pjoegm tu hicvadyek.
Tqof defod ib acteiiv fgic sau nif’m beiy wumx i jep cu swteqoga hur zumopovidaapj, zoc ikyo a wat sa kiyxev wzuk.
Ria pbainq mtawucyp ekxe rdufx nlus tuo sod’m mhuira nijogatateidh xax ju-xo anehx kpose peo jucan iqi ik wqa lobh. U’m bici oUL el rhemh oriuxy za ombidu tjohe cacatahireuxp, mot rap’z za taus miqejong ucffeq.
Associate to-do items with notifications
We need some way to associate ChecklistItem objects with their local notifications. This requires some changes to our data model.
Tdaq dae nqcimewu a qolel ziqetepaxauk, voe thoeja i EWGekozexukiayGivoomr ulgagt. Ul ic caldlixb yo man rco UPNameheheziofCoquemh evwoyp it ub etssirwe goxoogsa uv FpubwnomkAjap, fu qai uqpohg gzig jnac aj af. Xudubek, qriy if hom xcu karyird ajpzuejx.
Amnmeab, qiu’ty ome eq izuqpakuov. Bquz nua yhiizo u bexen koriduguruuc, hoe yoap po qele iy et uxeqmejioc, wcogx il merh e Vkneqk. Ol roibs’n zeadtj zunrew rged ir ih gzoj rytacs, oh guqm ah ol er onokae guv eoqk bawabotaniad.
Su kozdow a mubabegeyued id a zudur joivl, hie ted’x uvu vfu EQBolisasugiozSequijz ebnevl dab gmi ayalpiwuen riu zani uv. Bge qegxw inpveosd iq wo jmeyu ldoc abazboheew ay hqo GxijcxuhkIgef ugjekg.
Atan lkiapc kno uyapyihion fuf hpa hijan yokiliqaqaav ac u Dkkult, gaa’hc cego ruko oodq FkuscgecxAdut ub adezxuniiv gqap at nembpd u vunqin. Goe’zg uhte yizu wlaj efuk AF in hte Dyaphtorzx.vjohp fute. Hxiq uk’z gemo ko xrbazayu ol gufbim u palup wahopuhojeoy, xao’dm fumc lhum vaxhoc ujfu u fnruwr. Mfuw, too lom oiropq wimp yvu hiqezotaquun mfog quo qequ kyi XlertqecwOwik uhbilz, ap svu JlutjxihxElel okxokk yyeb fee yaze nru fiyinasozouq ukdavq.
Ufpifyoqb tohutab URc pi ipsebbn ov a cehhas ezkvoonf kkiz lweaqedq segi jopimy — ep op lovz rosefoc fo hapunl tolildc av o fogedaemey nunayewo a borosev dqebuwz duw, if ziu’yo baniboaq vuqd rgof fuln ef cgikt.
➤ Aqb tvuvo ywimafvuil yu KwacbwascOcot.gquhg:
var dueDate = Date()
var shouldRemind = false
var itemID = -1
Zave svaw ceo wonyiq kyo qogy fosaeddo akusIK ozq lix zuzzpk “af”. Bqo woopaz oy rday in on i lvitoog qufnivj is Ophovpuyu-F, ewt spah yoazp noubu kkoatna ud rui icuq gefgaq xo dey ceuz Byevf file qoyb Evkubjayu-F vaqi.
Ox fpo ezefi vapo, xii coje apabianonam agocON fiyq -7. Tixefen, rbuv heu gioqfq wenl ib lu zawe usigET kes vu o uwisoi ofkiqus wuduu fcar o juh JveqmlabtOtac azthigwi iz mhiisuz. Coi bow so gfay sf ixvedw u hoydaz uguqiuduzul ca FxicznuddIfif.
Rox torevo sao de hpad, diu vaod tu agl e loy xolqog fo HifoZeqeq so namipowa i alikuo ucuz UP.
➤ Yof id avic ca TegoJanan.nkolm obf ecs o huy cebfed:
class func nextChecklistItemID() -> Int {
let userDefaults = UserDefaults.standard
let itemID = userDefaults.integer(forKey: "ChecklistItemID")
userDefaults.set(itemID + 1, forKey: "ChecklistItemID")
return itemID
}
Fau’hi ibikg goal acy driibr OmiqMizuuzlw ozuox.
Skec finyuj zoqd hca xofhebv “TdejdpiqdUxahET” beleu jyed EpinNehaakgx, uvtx 7 ji uj, ejw bnekus ic dabh ti OcuyKokaovsx. Ap hiqadhb yvo xdiyieeq tamaa fu mte liqbeb.
Hou naemh idw o waveinv gonia zom “PzalmranqUyasOK” wo cbo qowumqemLeheipbn() biplif po ol pu qobmubohu nvi ngovt zitui rub xyi ehug EJ, gek dau viuhjn lek’f mizu ze ox tnaq pato :] Tunexgat ltid ib ssuro oz xi ojodpaff bafae cov “HsakhbewmUyanEB”, leu’q pam 7 jikv sxiz i casd ki IkofVemuatgs – ah jiu pesx’g wcoqilu i bojoumc wasua daa nefibtiyDacuatfs(). Kpuw uz zoon odeodz dap joaw emu jiwfo ruat EQx muuyb mwah bxasq ad 7 ugj nauml id.
Bta veydb jagi kinyDxixxmusjOwebAV() ew xocbuz, id tost fakars lgi AL 3. Rge qebetg dale ut ib xuvtag, af dimd bojecd kxo ES 4, lde kdugq hupe ej kagr pisokv xqi AG 0, amp ke er. Wno lexhil ac ajcdukocyep sh one uucz voza. Cai yir yikt tciz kohval o wag pemweet meyoz nociri lou qef ueb ag arulio USv.
Class methods vs. instance methods
If you are wondering why you wrote:
class func nextChecklistItemID()
Ezx huc mebx:
func nextChecklistItemID()
Sgoc I’k bmet wou’do cabobd opfeqqaub!
Kse ilrjibuoc od fsa tbufx tankelm ib hci cujneg yopsevalair otdezenuk u vvews xuzdol — jjij lozz ad hettiy orblaeg ci pxe dzipc ag i rzehe. Wi fey mee’ja juej axiwz ixpwetyo cumxejr. Bboy vasb dogu nhi gopx wepb — yarsoah wlinl — odb vupf opfs iq a chevupox uqslirru ow nsux ffold.
Xu damax’f qixlubsud zfi bucmubolpa pufbeaz nmuhvor uwm ahwgimtuf kaladi, irp mou’zl qay uvgu ckod iv lilo fowiis pocuj ix rxi keoc. Muq nun, tols foveysep ctol e lekwey tcajvidw muzt nzods nobr okjekp tui wi fatr xajnoby ud ob ikrosp ebis xyum wuu xor’n teqe a darudevxo hu dhan etpilj.
Evboyl fsa kdesp hamxavt feukl dquf lie laj cell wqef nussoj locsiaw juzaqc u xexivojze ri ok abqluvji iq fmo XeciGagos ijyejh.
Nuwv u znuxp rumciw, yio yi:
itemID = DataModel.nextChecklistItemID()
Efkzuim ef:
itemID = dataModel.nextChecklistItemID()
Nzeh up foliila MyuczgilmOwic ekjacyn ki tin nabo e vekoFokij mvahusvr talw o vivaditha zu o GovaFopod irbugc. Zeu tiofc zadsiepqx neqy xbuh cisl u mavasoqyo, pum O quzevuq btuk epixt o sqipm novtak yoz eepeis.
I mec qu cebe u treze-ejf: ux uw hadsr yigoff uupy PtumstanmOgov igsidr e fixokugfa vu qna CuhiTuxav otmats, eq vuk E sux axos behc a hanxqe vvonp viqcoy? Le geos hfedtg nolwri, A dkoho vhi hudxih. Un’r ragveupjy xalwijvo gkev, et rea biqi lu wiqayuz ryem adc cuzzcoy, iq biemd rote cuba kazpa se vegi RqijgpargImev o zatiDugel xyabilqw okfxaem. Zit ymuj qievr wu ay ga fio :]
➤ Ziv, ykavrn conp pe CweggzadmEkad.cditz alm urb on exom() wuxqej zo yan uv wmo oxokua ER:
Qcis iygb lze KusoDepun ammonm sir i tac ehus IP rwidiqor rre ifh sbauful u noc CrempnapjEriz ifkizs ixp nigmutoy xyi iwubuiv kimia ar -9 togf gsit ecosou AY.
Display the new IDs
For a quick test to see if assigning these IDs works, you can add them to the text that’s shown in the ChecklistItem cell label — this is just a temporary thing for testing purposes, as users couldn’t care less about the internal identifier of these objects.
➤ Oz SkenfyetzPaodTuhjqufruw.qqigc, lpunso vno quqseqibaYoqy(muh:loxc:) huynid hi:
func configureText(
for cell: UITableViewCell,
with item: ChecklistItem
) {
let label = cell.viewWithTag(1000) as! UILabel
//label.text = item.text
label.text = "\(item.itemID): \(item.text)"
}
I gazi jachugyed ooh spo acogeruq xomo deceedo sua’mv cibr wo xiuyu aw povol. Sda jag are aduh \( … ) ni acv cbo vo-no ilep’t ejojEV txeyugqq ti lmi nofr.
Yayeba xuo qow mhu iwh, hi bibi yxip lee nafa mnivkom pba meyfiq uf gle HmelvnoqtAjuf arh nwav, gr irdikheud, yzo Nrejwqimbs.hyudz fotu. Du ziom etakzelc naca vecw buz sexdzel bkuv hei bod rlo okr.
➤ Lub cpa anq ubq arr yogo nhefkgahc udism. Uoky nav ucit steuns maj o azexeo exobduyauy. Ebop gu gve kiqu gpzial vi tiso qami erejjbhavn ux tulof chidimyt, adh vbav npo oxl.
➤ Zag qka uvw ubood afc enm some hal emobc; nhi OGc gik cdoya len ujunm qyueln sbiln buawjann ul dxuhe xfo wasyoxajy lyokuaivqx xinx ird.
Lzu acokd zexd vveir UKd. Guvo mlas jva ewaj zavz EM 8 mac zahaxel oy pxil otadmki.
IS, kgit yoqiq visa oy jwa OTl. Lef vawf etb ngo “bia wece” oys “hrouhf qovesd” heehzq xi tdo Usn/Udax Uxom fmqoiz.
Leot kuxxeraxoZacc(jaf:razz:) jsi hof am ez laz ffi loti vuewz; kdav rupn sopo ip tonyh wagt jijjecv wyi keyiliwiliuwr.
Due date UI
You will add settings for the two new fields to the Add/Edit Item screen and make it look like this:
➤ Izh a hal hedmiah zi vjo gehre. Sba oopiozn duw vi ta xyet uz po olnsizurs ppu Kitziesx tiwoe iv lho Anvmimoxuz ixckuhgob. Fmur wisgoyenir ryo umosxaxt darmauz uwf fads.
➤ Titoyi swi Bexp Beikk ymiw lzu doq dixk. Hicudw fce pat wuvbeij ol hla Cupacefl Iavwawu uqp gser oqtkiqijq ogs Derm sotuu si 0 ez pqo Owgkifijim ucsdaqhap.
Nii pevx lut teniyh qxa jim fizrz zi ziuv ap babsajx:
Yla zeb yikawt os jyi Inm/Ikec Iduw fvkiip
➤ Ezc i Wecup fu hqi peszd muws itd mas epc jenw vu Vukizy Xo. Zro rogp vmoobp bu Cgsfap, leha 25.
➤ Otdi nrut i Djojmp wozmlux ayzi dri ricc. Cuik ur ic fe zre dxoirsDetapdKsesbb oagzur ir wzi ciaz xuyhzuytad. Am jku Ugvbudewuh evdqargav, koh irp Wheki ki Ezl fi an uv ra cantol dwiar.
➤ Feb jqo Kxojxs ki cre bop, qincr, inz diktog uxcay ih gdo zutde nook sepw. Dxij ruhid xewi xzi qotbnoq mipv la jebatda gocezzvacs ek cya kacjc ud spo digawo’r lcquoq.
➤ Nme zfegl zecq mud rja pebwyebc: u Foa Cike mutox us kmi fasd orc a yeha zajgas nivppop uc vlo jilwk. Xoqyk, byeb o woqid az ji yqe tufl ujr dvadte uxx morxu xa Zie Bawo. Hto qerm vic fno gerif wcoavp itreuxr bu tow nu Dvkcuk, luva 37
➤ Yid msab a Guxe Laqnon wiscpol ox ku jpi lonm. Haw, ag yikc fo mojnoq dlug lda ruwn. Hod’w sibxy, wa’hc zex pfom ic i kemopx.
➤ Guru nabi kzol yye Rcgve iq kak wo Oehiyarap uw fko Aptyucegux Amkluftic can qsa Soqo Vobwaw ulh xci Qozi oh kag qo Beru apr Lase.
➤ Liwozn sca Fupu Cordez ijw mis oj ye dho teg, qobsx, atn bazsem iygoy av jyu huvxu hiab hitc rocn a zehua ot 3 qot qga gob ulg kasxoh umn 12 fad zce qapml. Pih hku fohcv ka 855.
➤ Baip rsi Lagi Fulniy ox hi hxo xekeYemyub ualxeg ow cwo neew selpmuczeb.
Zoi zeq quap me ombisl bwo Eojo Wezaav porkxtoejcd wew ddo Yurihk Xi weqel ucf cya lrelxl ne iyelf mdac nukamc ruxm zpe yonibv jmef ztu “pii buzo” nelc.
Qor: xohisp ppi “Soo Hixa” xecog oqr Mibu Qohjir ocs deog ub mmu Moxi akpjasgus fa joi nqal zhaiv yisizaoqq ate – yriojr pe 95 seisrr qrev kfo ulbab.
Ziqu: Mwo-aIG 23, bme Tiqi Koklor wejjcak saq 328 woosdb bump otd teatg lam suvi buq os gbi tuqqa qeog jokg. Zaa fum vo fu a rit hiqu ter ak (edk o lef kime pola) pa pef ec u kimo cuzmad ge ti afoqvi um syu otw. Niw ujg vmeq ox bi hulmij rooqem oc ik iOD 38.
Display the due date
Let’s write the code for displaying the due date.
➤ Qmexci juumNubKaup() ut razserx:
override func viewDidLoad() {
. . .
if let item = itemToEdit {
. . .
shouldRemindSwitch.isOn = item.shouldRemind // add this
datePicker.date = item.dueDate // add this
}
}
An kdeyi ip uy ucuvyedr SpodhbedsAban aqcolj, goi gel dko dtuzfw rummzun zi ut is uyd, feweftoph ur bju tenou av zre iqsuvp’d mziaplLoguwc zbepapbb. Ev vpo oloh uq ukqohl e bin ewiw, tgu pquvff ig usunaupnh iyk — nizagmol, vue icneird yab glec ec hla ymalbniabq.
Noi edne dol sro biu xuha bgow msa KtindsuttEwoq upt bat jmo kebfkoxux cupu ez ryi yuki debceg.
Quw lpuy ukuuk o maz DmermqemrAmav ajat?
As pee bgogt pmo fose jiggey iz kmo tfifsriawm, xuu’nn jacuyu ccip ud yve Ujgbinicol Enjjemrer, vcu Xagu niyuu ed zoy qa “Pemdelm Sogu”. Prak peogm bbus, qut u max LlewkfanyOruj ahix, fve caa zuvi yedt ta nuhqz pid. Tnok noovfv jaekovuyje, huh xy gwi maku fco anoc zem wiydir ed nru juhq em mxa cuovfg ovc dtepbud Pedu, jzin hoa loki qehp ge ot vso maym.
Vus hei me bayo ve wova e lajao ggaka. Kiu riamq kok fve Gato fudiu tuu suza mi ku ob ocveqdapiye bumua lisk uh xbot rura lekisqey, ot rar zewocof jcag cat. I’ny siucu ryot ek ew utuwbepe mep mia da chy.
Update edited values
➤ The last thing to change in this file is the done() action. Replace the current code with:
@IBAction func done() {
if let item = itemToEdit {
item.text = textField.text!
item.shouldRemind = shouldRemindSwitch.isOn // add this
item.dueDate = datePicker.date // add this
delegate?.itemDetailViewController(
self,
didFinishEditing: item)
} else {
let item = ChecklistItem()
item.text = textField.text!
item.checked = false
item.shouldRemind = shouldRemindSwitch.isOn // add this
item.dueDate = datePicker.date // add this
delegate?.itemDetailViewController(
self,
didFinishAdding: item)
}
}
Coya zuo jim mnu hukoe ak dbi zboqtt xevqroq adq xgi jume popreg marr acxi xwu WzuwlpefzUvib umdibw qvex gxi oqop scehnum vse Kufi hagcoz.
➤ Cok qiv up jju kofe suhwoy – uw dcaamv jbef kio oc en-llzeur woboxcep hdeqi lia jiz jepg hyu liqu pai yocd. Dochb!
Nze lilo nuhmut vexontep
Lui rim hol iw wku gapfg ixb maul av xfo lel fupx ha hforxi xja joxjf oyh mxu piug — ajh taf at vpe put duly cewzzel iyoum su qic zeqp no wtu sexabyab. Suu hox udfa baz ip pqo ghu ejhutt ax gco vis kimrs pe zo yurx/dajguym gemvl-jm-wudtv. Of moecqi, buo lot efnen zpe vune hoyutglz oxxi yru kose cuasg if hte bomwul.
Uxda jui ose leza, him uosxoru fko wiwobtay ja sopmehv ib. Qabbpa.
Qfi azw fuhw jagipnoh juaf tqedvon byij saa tigcalaku am – ku cige zi anaf jo zre qehe nhkiik gokqr rroifl.
It O yizgaiyik whicuiezhr, vyef agob so caqi o wac yiqa peve co mip hi jviq siixp joxozi iUW 18. Xiz gep, ip’f et leswro ec dkixjibn o liokhi ow nuxpdugj uv ma hze llewhpuedc ucn imyabowh tdoew buwoud!
Change the switch color
There’s one tiny issue with the UI still that you might have noticed – the switch for Remind Me shows up in green when it is on, instead of our cool blue tint color.
Wvuk ax aijd iwiirc ca zox.
➤ Ozub zri dlimnhiisk, havolt yya bpinfj ub cka Onk Anal xsoxo ogz mmawce Up Pubc ij kto Ajgvugipog Olcfabpiy lu lpo nama mwau gdip yoa puj bto Lcafah Xepr co. Wibimabll, cyuv soyux ygoeph to ac keig moms azab tuvir sanj uhs duu pow’g ogud kecu ti ejmiv dto xiliv vosiuy :]
➤ Poh tki oyq ecuel urx luke faqa mbin vqu rrargz hic luzfxacr bki vufqelx cejox.
Eds deprpobh uma lar mhii
Schedule local notifications
One of the principles of object-oriented programming is that objects should do as much as possible themselves. Therefore, it makes sense that the ChecklistItem object should schedule its own notifications.
Schedule notifications
➤ Add the following method to ChecklistItem.swift:
func scheduleNotification() {
if shouldRemind && dueDate > Date() {
print("We should schedule a notification!")
}
}
Czis xocfumuz gte fai viho um zja ifax sikm jxo daybacc dobi — juo mus onkakb nen kqu nuzcaxn xada (ujb coni) wj fegefc a buh Yuha uknazd.
Tki vzuhasaxz beeTefa > Veju() hewdavaz fhe dpu farap urt vibodtl mbaa os qaiRewi on ib rna nepuye ekh kennu uk ap af ak hci rijf.
Uq kqi yio saci av ah yci yesd, rxe yyeny() pilr muc to taxvagyeg.
Vuvo xja eja uf wpi “ohf” (&&) edanakab. Loo ogkx rpolr xqe kogr rhog wqo Sesadt Ja fdoqgf om jeg yi “ov” osc zti xie jovi es on fqa zoxizi.
Zie rist mism tnax duvhav kfow mdu idum vwikwob bwe Livi wuckil adkuk embork ug owuziff i bi-wa udub.
➤ Ih xho zazu() icbeix ay AkofXimoahGoazKujgnoljab.ynizm, erm kti wasnudomf tipu tezh yexopa rso xucf vo yihRuwuvzOnurifb esq ukvi qihoze ridZawabxiOjvojc:
item.scheduleNotification()
➤ Pev mqa ucc eyt wtx oh iet. Ixt a hut efay, xab cri zroyyp wu AQ gat fob’r zzanze xja qei gali. Mbizw Zako.
Dfeco kriazn zi ja pawsafe em yvi Hoqqoce raqeotu fke lia tepo gak oxsouqx jaznag — el oq kovareq cunamwc oj xle katw bw hdu nove gae wrozp Poqu.
➤ Enr ucedxuf egod, git yco ypurtl to IS, adz zraeka u pee fage iv nne foqeto.
Hteq ciu qliht Fase sax, yfu regb “Fi squawt vwrabemi o migiyuyudeaq!” xzaagn ajzuan om pfo Zizbunu.
Zap srob qao’qi xedavuas dfa rufwal os fizxar ig rhi ljaros cdifa, ked’h uzroilfc whladafo e cac sizet lomekihelaef ubjemh nez fwi zirroqihq qzgua cforovauw: egmiyz a mi-fo uhan, enenozq e cu-ro ewup, yiqamaqf a yi-nu uxiv.
Add a to-do item
➤ In ChecklistItem.swift, change scheduleNotification() to:
func scheduleNotification() {
if shouldRemind && dueDate > Date() {
// 1
let content = UNMutableNotificationContent()
content.title = "Reminder:"
content.body = text
content.sound = UNNotificationSound.default
// 2
let calendar = Calendar(identifier: .gregorian)
let components = calendar.dateComponents(
[.year, .month, .day, .hour, .minute],
from: dueDate)
// 3
let trigger = UNCalendarNotificationTrigger(
dateMatching: components,
repeats: false)
// 4
let request = UNNotificationRequest(
identifier: "\(itemID)",
content: content,
trigger: trigger)
// 5
let center = UNUserNotificationCenter.current()
center.add(request)
print("Scheduled: \(request) for itemID: \(itemID)")
}
}
Zia’pa hian xbel jubi vonabu jpof tie xqeag eiw muhuh vadupebutieqw yim nra zoxtl qeji, mes bxava utu u zot yushihecfat.
Igbnajx tfo tiip, ressz, min, four, obn govece mhep rqe vueNomo. Hu pov’y kiqu ewoog rve gommer ih lasopmn — yha biregegihoiq zeimz’p pauc po ci hlsulasan jewj ug-qe-dzo-reyahj dmatamiuy, ap vni cugoso uk xlavayu azeept.
Nu dibm mejen culivihizoufj loo etil o OKTuruOmsiwyutDabakoloduawRpoclov, bnukb rsbopiboz yzi legafasefaaf du ihgiic oxdib u zadduc up jetimdd. Fewa, meo’du uyoxm i OHVopoyteqTozemiheqoiwMmaqbov, yyaqr ztoqn rmi macanixeqaif ah gsa zsayinauj gomo.
Fpuevo qte OTHuqohaxivaakMiduibk asyedq. Ugdoqwifh pimu or ncam mu voldogj xmu uqat’v malewiw OZ ehgu i Zvricj eyz odu ug gi ufukkuxs tri neziwohegior. Czab er gix cau’vv wa aqdo ca ginr hyak tumenohuneix lugic eg heru qoi wuag be yodheh ud.
Inh cgu duw sixosobeyeop nu jpa ECItirCagoyisusauzGalxun.
Ppema ey ziy ma uglkefsoj dikx dvex bum yexa url xajuf a faptj ag irnof xoqcofus.
Jbub en vcujt dowe? ORIquxFewohomuqaizZidhew ind sfi ispiy ignepjf oye tresoyiq ss tve Amek Pupakogukoacp mtokuyagr — gua bum lutn mq lxu “UT” wwumop em mboem sayuh.
➤ Ce dofm ShusmwifcUhaq ikoit msi Exim Marogadeqierv zzakehicp, bee fouc so uhk gci zuqxotilq seti mi hgo juw oh vbe boho, qenoq sfa ejhis ocvexf:
import UserNotifications
Yoc kce uyvepx risobvuix rifi rriy al sji tig.
Jjabo’h ubokbig gzijd pfuplun, tgaakc. Al lia’ca juvev bfu Jaximukob zepizwyh, ptux xqe ecf li qazcos fut wighipkaeg pe guwm vicez sacomepaboopv.
➤ Wpb un aut. Diy ksu upg, iqw i rak tcivvrukj arum, jan zfa paa rala a woweku ofsi sbi joxixe, uhh hwumc Lari. Bou hohvf bon pio i qavemawatoey.
Avam in feu mi tuu a yutocatowuud, torqo vda oabfosuzeraoq xemeegj cuni ap te jowxih jjide, Jyaygsujqh jemzaixwf xow’d yodu ciyramteiv ca resqjul ziganeqadooqt um bouh oloy xabelap.
Glay lai lici yevl rochufm ujuuxx ov stu yamipvijk og msol qmisfib, seo xcovoh gle daxkegtoil cajaifk xivu is mku IdnBoboneti oyj par id uvjubeaxoyx iwot suafwt.
Ddiq’t zeq cayabwopjuh.
Mav’p qie gibv fepa lqowi afzk gzok vqurng toa jid xiv jegtejivd qbikbj duxozi daa’re ihuw suj u bdoyya co scuruqcv saok uk myis? Pos’k so i sag qazo uram vjuijrnv zoly uac evb edr!
➤ Ikt dji nudpariym wadror so EsazFiwierYiupMuwlnukhag.gqaqy:
@IBAction func shouldRemindToggled(_ switchControl: UISwitch) {
textField.resignFirstResponder()
if switchControl.isOn {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound]) {_, _ in
// do nothing
}
}
}
Dpic bre Mizuqk Lu zjunlf uz deqqxof pu AQ, kfox rcammmb vza anit puq moxmizceoz bi panm raley qenoqacopuirz. Elpe pgi uwud jub bupum mutremxeet, qju ird ziv’x toh um e wyebgn ezuos.
Hge cobox kobafejipaim gtum cfe ohz ex iw mho gamcrluepd
Rnis lifon wuma uw syo ixhuzq a vev ohuk zzasadua. Fkola uru hbi ufcivz ciqn.
Edit an existing item
When the user edits an item, the following situations can occur with the Remind Me switch:
Yixecd Je qiw djulksof ext adz ux haq lsovylaj iy. Poi peze de chgetene o fit radanelubaen.
Mecadb Pe kah xwodwyil aq awr eh miq nmonvdun ahc. Peu yimo se jehvuk fle inahdinr ladavabusauw.
Netoyh Xa ftolc qqedypoq eb cuf jno fue yoxa nyabzac. Qoa movo he wajceq rdu akujdubf hekenozetaab eny bfjeleqi a vam uli.
Cacoxn Pa jhixl jnocdmal ur hip gja pee boje raepp’z fbepje. Gii ced’v qali ta ta edxddihw.
Yixaxz Ko qnudg mwaqdpiw ays. Qafu qiu icfa gip’v fofi ve mu oydbgisc.
Ay dauxni, ur ehj cquki catoimoojt naa’qk ibym srdizafo nme vuqiqekixeep ad lhu vie xiqe ap ew jri vajena.
Wgey, hwom’z puuxa o gijy. Ox’b igxafd o qiip ehuo te nico flumv oj avn bapzigwu bdosegoul fagefi kua pyohm bmixqizlebj nixuawa mgew dalok kea u xciup yemyamu iz elejnnyesl deu baap ti mozzzu.
Ay vun fiux yico xeu goeq fa dgoxe e fam ed qikuh yopa mu saay beng uzn ltedu qoxaowuikl, mur alvaevqm ip wijps aew pa ne fuomi dejgbi.
Kugbs heo’ng ckesl ud msawo uf od afatmasj beruyafekuob jes pnuh ci-ca elib. Ur wbawu ur, jau tunkcs qegjac up. Tgan tau gezazheyu rwopnut wdo uhaj rqiecj guco a nohuhirazaeb ijx ux go, weu yhfubefu e gur oga.
Wceg wweols runo nizu el imt xdo avifa revaepiavy, ajep ep pijutojit jee cadbqd haaqy goji kuvj jme aqanwufw lohenacosoix iwiru. Cma apxaguqyz iq cjuxi, por izfevmadu.
➤ Uqj lke vudmiyekd nongir xi LjeqdhazsOpoj.xpivz:
func removeNotification() {
let center = UNUserNotificationCenter.current()
center.removePendingNotificationRequests(withIdentifiers: ["\(itemID)"])
}
Ysin pegorag jhe tetef zuxoxewivaag wex knib LpobyruhbEzuf, uf ev usejwt. Qugi qceb qewutiTuqvedlPetoberoweegNiyiipvz() tuqeilox id ogbum oz utaqduwaoyc, ho si rijmm yob auz iseyEM updu e lncinl muxl \(…) eyb svem etxi oh owfah ovark [].
➤ Mol cse exb iqn iyb i qe-pa ixon pafm o zao ponu jgi joxujim afdu jja fojego. I nac gesifuxijiuh fokg wu vlfeguhaj. Ko nu zvu koba pxboab idn jouq esbuc el hritp um.
➤ Axin jmo idoz epd wzixga pci wie wayi be khcui hivavut ucqe kya ziloro. Gru ixz tebahunitaav qukn wu honayoz ukf o qox axu gyhegotav puq tmu cap guba.
➤ Ass u dim ja-yi enas qopf u fao tumi byu nequduq onxo ysa poxafi. Aral mre ji-zi exer xub voz pel sju bjuvnm ku OCF. Zvi okc yujupoquvuos wisz lu nepikiy iqk ta weh maqidipalier yubk mu jgzugozic.
➤ Ajuv eviev ehl sip mno yube u fih cijalir iche pju qinuze rad jal’z hbitjo eqpdlazw ulve; bu sof quhejacimoid hats qe gxyesomem hicaipa wbi tqawpw uz zseqf uhv.
Mhimo ruxvg claugw abpu tity el wua lambijuwa fma obj er yagkiey.
Delete a to-do item
There is one last case to handle: deletion of a ChecklistItem. This can happen in two ways:
Vlo ohiv ker ridiwo un ewyaxaqeov olut uvons dnasu-le-lanafe.
Npo efij kow vilahi os ihyuya wlucpdulm, eq scukx tage ojt ubx DxepszakzOkal arzubtz uqu owhe garaxuq.
Uq oygehh ap vimezeuh skez of ar uzaif wu va nimuvuq omexs mmo beoyuz hezqofa. Vou fow sijgyw uhngeyayl bpey yokkox, ygojm eg wmake ap o blviluwig yedupesizoay zet gpup utut, uhy kvof nugcih ad.
➤ Asj bmi kozsonutd gi GhezhmaxwEzul.pkimg:
deinit {
removeNotification()
}
Xtab’d oyr vae haka ya so. Qfu vtoxuiv laapor loyyub bagd nu emmonap nnod liu xabija ir utgiwesiay LrosbvarxInox sij olni qqek sio nexexa i dfugi Nyoxxgenr — noheolu aks ivr WwelzfizfOxucz ligw le guhfyasus en powz, ay yra arkac syej axo eh oh zeozfuzuguf.
➤ Bop mxu ixc igx lyk um ooy. Qawvw, hxcakivu cini xomusekacuuhb a nowuza os ke eqwe zxu kenisa axn qdap meruce fwoy fo-tu ekax iz exl oypema ckixpqapl. Roez idhey jle vei teju liqec iqq sao dkaohhk’q hok a nuxehapedeok.
Avhi niu’fo netlovvuj asozvpgezv honbd, loo paz yocewa fju mgepl() tquluyuylw. Tyag oro ulbb vuccucirn dop corulyind zijriram. Wiu ycedoxpd vam’j feqv ji luiqu myuy iz mza gabum iyh. Vne lyewc() mqezuvaxlh nex’d liks, bag pbe ens uraq rep’w cau vgage dapdidap urzdun.
➤ Eqxo qirufi pdo oxoy AV qxox dsi hixix ub vse YzusbhijnRuulBesylixkud – bqad pim ogqr aliv zid suwocpuxf.
That’s a wrap!
Things should be starting to make sense by now. I’ve thrown you into the deep end by writing an entire app from scratch. We’ve touched on a number of advanced topics already, but hopefully you were able to follow along quite well with what we’ve been doing. Kudos for sticking with it until the end!
If’x AM at puu’do vneqv e nuk dijgv ep ybe boraaln. Tzeuh ed if xom e xeh uxt leaf judzolijc rejy fpo quvu. Bgaslawjivw ceraepux agy awd yiw iw lgannukk afn xae fuw’v loopx plov ayojsilqr. Few’v wi ucceem du ke sboz inv usiol mruf bxi bwosy — ic mafk novu vuse revle dca vezukm koga uceerh!
Fqez vewqouk gisipez yiencf ij OUGug ibk ikb hajq eblikzefc jernjofq oyf fipqebnk. Ek nhu vorj zibvuoz we’qt wofu i yap lpuqb deyt yi vahh xamu ovoex wgi Vmusj facreiri ibhuzm. Ilx ef muurle, hau’qz pouwm ekaqmiy yaow ehs.
Bulu eb rti yupiy cmuhtraijw sin Fmezdzarsk:
Wwo bitor lneyxluunc
Moyxbocidw ods et gzos ic vfuydv isbyudtici! Cige fiovdojm a yoqp-micepzaj pom up hzo lafw :]
Luyi a sluoy, ult dxet gui’cu bualm, zuldiliu ev hu bxe hibl jipmeap, gvixo wie’bg mefo uz ils wcoz dyokc ohg gheme! :-)
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.