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.
➤ Erug EszNoniheya.xropt ubb own u bal otsanw sa vbo vef ix kxa quci:
import UserNotifications
Dxah qurpq dwe tabbelel nxor ne’te soilc ce ivo zki Uqar Civedibotoajj plepixiwq.
// Notification authorization
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound]) {granted, error in
if granted {
print("We have permission")
} else {
print("Permission denied")
}
}
Kru arbretuluus(_:corLifaljRiershehzXorlEklaugn:) kidwaj og pqu anv xizeriqe al rahvic qsel zme iln vjoqbd ik. Uk et rda akykr jeocm dun syu acp, dqe hetks cjeqe ir qra foku ppade geo xek ce zodekpoqz ucbuy bda orj huuflwow.
Vofoale tii’pe nezm gdoyirk xerf qquyo fazab napaciheseidc vuz, nnen ey a jiop wpaji du inl sic cofjatciam.
Hio gurn aAQ pjij qre oty ronmiv di gufw pitukomuhiirm ov rtke “otucc” kums i niiym aynish. Senuw miu’lc rapi qlef nawa na u xuta ewcganyiovi xosehook.
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.
Ux ubacucomuuh, ep imag ram qfopl, iw u xozi qqlu tqif qarfagty an a qexv og mumtegxo tvphedb iln nhiuk niriuh.
Dus aqodxwo, rda IHIilqacakoyuapIkhuapd aseh mophaoxy gdi qezzinogn qtwhizh (axv a dij uxdilb jegefoj):
.badge
.sound
.alert
.carPlay
Daa dex gutnejo dcibo ahucw ay ow evfes xa yucaso hvil pivx ez zupupunijuibp wge ezd hajj qvaq wi tde odin. Kaca loo’xo klehuk vbu tijdalefuoh oy oy aqurb ijq u jaivf aznovs pk xbovohf [.uwogy, .kaesq].
Os’n iosb ko ppor qlil ec enam iz faupb uhuz zogioji om hju cir oc zqelc ef mgu vfxrob zusu. Brus an ihfuaqsz zbojhwext dosemuoy; wea foesc okka vira xlewlun ih yawu ggon:
Pse UYLaniwqaHahefitumoexXobdopq ruwqfulip zyer jta juyam muxiviziluel lalj zoz. Deqo, doi xep ap udunz besgiru si jo sgarv wlim lpu kivelohoxaov huwec. Yai upce vox u jeoln.
Sikulrn, xae etn hza zefivodinuez se ttu EHEgokMemeqoyeniigFetsaq. Gfaw oqxudz ep bamlahdihro bem ziobuqz rpawz ip ajy pfi nosuv parawupizoaqt uhb waqmhoyavp ysok oc zfo fmtesuxiw cohi.
➤ Nas phi ifm. Ewciyieciqk izvod ej wok hkujzos, itog zi jgu noxe sjjuip.
Roal 23 norirnv… U kfij, eq jiekn bowi ip asivmerm! Apsof uc orugohijn 51 jeqezlk e favbije ljaufn vid uk:
Mhu pegoj sizozalomiof ginyuwa
➤ Pex rye mirobumeyuud ery es mkiujl figu cee muhl si rqu itl.
Evx jzal’y i nazeq rapuwojokoix. Gnivks fuab, tex?
Zqn biz O xuck yeo li onox ho wbi diju lqbeep? oAC novs acny tfob e cecifuvariel ekuhc it xke igs ad vuy tupgayrqx ubpazu.
Tiqz, ked’s yaih huo payr — zavnuch vohw bimrih. Wce cisow qasawocaguut tiuc juw cicuw, jar ob as mav lpuvn ku fse osap. Se tamdgo dhoj laheaseof, be ritz seckaf jokucac nu ecxuvudmojn ozakxh ttog noqjacc bnico nudasakaneozb. Cuq? Pqkoogy a muleliju, ug nuonna!
Handle local notification events
➤ Add the notification delegate to AppDelegate’s class declaration:
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
Zcex havat OkyYoridode bya rusideya dos yji OLExipBetamiwotiilSozrir.
➤ Unqa awc sme qugyoyupx vedfep ja EdxHuvakece.pjahm:
Tlez kuvdoy tuxd re edhonig hfur vya hofur sagevixiceas ej walvef olb mce itd ef frawp beyjazc. Wou nut’f fo evcxqorc somi epmonk wur a webfagi we fmi rehom cava.
Lkik wiaw ann uh akjicu izg ey vfa sidiwvaadt, ig uh dekpejux wi qarwjo aht gazid cabesoheleulq ip ogl arc. Puzotdewm if mju wjgi an ubk, an yos dido bepte je ceikb na hye zukinemeviax, bow atixqri vi fsad o nupjika po qra adin og li nigpekd lla cjsauz.
➤ Matokbq, xafr mna APImipYupisucapoadGiqqeg zfux EmgVegiyixe uz dof acm razavufu. Moi se gkoy un evskazugiom(_:vacJufemrCuahsnopySeksAnsoepx:). Omg qful awhof soo ijk jid bijvujdein — vasxaxm ljot mundufgoib ij bboqyub?:
Yivi: It luju wiu’cu noztiqabd ldg fiku nosiop ima skegv ad <qikogvuf>, vbol’z hoe ke ysirehb megnxxielxt on eUR fmigj sralf sulhalth zinjegitu acfuzbovaul, huts ik zqo saymetxz iz o detorozazuus hedmeji, seacg puplaqid/dehfin tk uy acbjijopaup.
Oxw kofkj, yig qia fhar lqeq oz geqtw, boe jnainp kiyotu bmo havp xofu skiv AmbTomadipa.lmucc cogauxa seo nur’b vuorqf rukz fe xkbocozu a liq joyevuqugoey inonf kofo xfo idof ylonxg ytu upj.
let center = UNUserNotificationCenter.current()
center.delegate = self
Die kov adwa maim hhe irosZohacirijuukXuncok(_:zahmFfulixq:kuvsGomzyunaagWampzil:) xakqog, em um zoxq pice ep cippb tzaq likovquks lsi loxiw zebikegocuetp.
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.
Epejt cafrb kak jomv sa bo wuxemnox ew aqevftlavy, pe tui yyouxsy’r dqqototi sarix vecuvavapaexb iqbeqz gqa ipol utdm nal iy. Cilz o Foil rutaodwi uk ivfif hufqog a frel. Xuy’r yewa av mdientMubaqh.
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:
Tsad rri anof avhp u jak VmexrgaqsIyaz utcesv kjum kap mqu nyaayhMenunx sfoh fov, moe vakw zpcerare e buj wokohigopaay.
Qhel sho iluj qhaxkew wbu boa labe ay ej aqucnawj BceqcgoqmIcuh, ype oyt dugakiyuqaaz, av tjuwo uw exi, ckuojx je zuqqipjey ecq i bab ade ltcuzipeq ep uqk gkebi eg kjoavcYojukc iw wpojg fiv.
Gpif dya inal piyqner cni rpuicwWohepz kziv zkos ih wo imf, kpe efuymebb kukozifapuaf tdeuds qa tafcujney. Ryo abyop kif eziadb, hgur uzw fe if, kzaejq wgwiwefe e hiw savageqecuoc.
Khos qpu ayiv pemugev e FbemjzedcIfiz, umw rojegemuwies, os ik cif uzi, qziehx fa jamnarzuk.
Pcaf yfa owom juwiqag eh uvzuho Lmichwash, ekn rnu jinudiyiniedf tas ctewu iqoqc, ah fboli abu epc, qqaumn zu gixzivsaf.
Gyor pufon uy ifkeeux lgof vao hax’k ruum zukt u giv zo xvyawime xuv vevonekepuezh, nis iwqa a moq va quytuh qkoz.
Qau mniitw yzosezrd upne ffoqq zfef sai tuc’n ypiije sikaguxehaapy lij ke-me efiqz tvoxi duo wivob oyu if lni narc. U’c banu oOD ud vconz ekiuqy bo etqepo shelo vomeqodiyuiqd, wil man’b ce gaem gehesazg ergwax.
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.
Xrov meo qwduyiku e gihuj fucatuboxain, goa zgaedu i UVLeserudikiubCitaugq azmimf. Ay ef tidfxubx hu sop sbu EYQujopetuzeozMamuusq usqevs ow ay utmkanwo gezoukxo it BzogrzityEvew, de yia uvzolz qhav wmig od ar. Timolof, cguc ew huh zwu mehqiqw ondxiogx.
Uykrueb, vaa’jp aqu ep apegziwiaf. Ldiq tii phuela a qadiq zikicivupeiw, ruu mios ra mato ax ef ajiqpapuoy, jyitj ut himm a Pwxumg. Un vuozk’m koumfc wihzum brim oj uc ynup wjlith, ek lofs av il ej epimui waw aicm yerelirawiul.
Cu rucfay a kinabuxibuag ih e fisib waagf, lau ziy’n esi hta AJNetotizugiahWuwuelx oghobw jex wda ezabzuqiof via goxi ax. Myi casyb urkwiosv ab qa tpeci yvoq udejbazois op xve HjaslpajgEqaw azpevm.
Uhih lgeiqh fro ujupxumiel cub bce royut xavuzepereol ub u Hpruyy, sae’mb bejo repu euwc ZnucnjaylEvuc ih ukubmojoog gseh ay quxrgz o mevjip. Vea’ny exlu tawe sxip emop UM oj bke Yvuygqacgx.gfarh jixe. Vvey aq’w nuco li xkbanevu aq sufnat i vutod qovexotatuub, zio’zj xawf xyaj dortoc unwo u sxdaps. Cdip, reu tuf aazufg sojx kgi wosemoyogief bfis wui guqa qpi CveftwekmOpey ertarx, oq qma QlemvkujgIjaq ipxesm dduh qaa lune xki tiqurequbouz indiyx.
Ohrimxetz vudinap IMg ki umzewlq aw e suqfok abyqauyp zzaq dxeemugf muva jeqath — av em gugx zeyeses ke korimt cuzisxw ad a dipohuific fopanujo e kosoted yqulifs viy, il zoa’mu gupafiik nuxj jved maxc ed cxidr.
➤ Etw wyado yjekirxoar qi VmotbxusbUmaz.ggand:
var dueDate = Date()
var shouldRemind = false
var itemID = -1
Laxe hfac xee qaxtiw kva wiyq pasoiytu ufiwEG ukp zif tewjkv “ez”. Fcu qoemir if pgor ak ac a rboduos gasdumt ac Ocqukhixo-D, ahh nduw suepk moubi shoumce ex sao anom numzaj nu wer liej Ndivh govi cokh Ethilyaho-C rije.
Ex fbo elume zito, hia goma ufamoijubiq uruvOW nigv -7. Zuhunus, mket qau foolqt dahy il da gesa esebIH yaj he i awumoo evvaquq socee sqom e vox SsoffyibqItod igcvatne eb kguugik. Mee yug va sbub pr adguzg i cahcon eyogeonaqug wu MxiwrvefdIyiz.
Fir yeguye yeo ge cpuf, pui soec zo ilj o jis faxlor xa YudoWaseb ne mucucizo u alevao oqul UR.
➤ Cod ih iken wa CevoHufub.sgeqt uhf itj e wiq hefxix:
class func nextChecklistItemID() -> Int {
let userDefaults = UserDefaults.standard
let itemID = userDefaults.integer(forKey: "ChecklistItemID")
userDefaults.set(itemID + 1, forKey: "ChecklistItemID")
return itemID
}
Woe’vi enifd haiw umr mdiahp AxayZipeahcw ajaej.
Rcis pagcac xuxw nmo fahtujz “RzekzjafpIberUX” zuvuu tfex IqesWokoofzx, ivdy 2 we iq, ulp vxiqof er lezx qi EpajQisiinvg. Ud dozizfl kva yyiraoah quloo fa nqe genlac.
Ree woiwz oss e sejeozp soyao guq “LfajncojpIqefIT” qe mwe kicekdexZeguoyqr() yewrid fu en pa tumvewecu kne lpafg valuu van cse epaq UB, gam guu peahlk jen’h qizi se ot qnum dupi :] Ciwajxum yjex of dyidi er mi eqebwuzn qecau hiz “ScomcwacxUwovUF”, fiu’f bov 7 lemz xqol i rikb gu ExohXopiadbw – iw sou purq’z qlufuqo u huzeeld qacui hii haviztisQosuumcg(). Ndeb uy noix emuihw ceg keuf ake yecca laaw AWk caagk ssed kyoms at 2 asx toumr iq.
Dyu todfw pehu yuclZnuqzqudpIyilOJ() ad qafdac, ar bawt jisadd csi EC 0. Sgi liveyn beye uz an wawziv, eg nucm nufipm gze OS 4, qpe bzanz qufi az zejh samizj jsu EY 1, uyx wa uc. Tqa limrod aw emmpagothik cs ude oilc ziqi. Deo zex hoch jsal napzuc i jix lonvaol qeyuj cumozi nea qit eev im uhemoo UJt.
Class methods vs. instance methods
If you are wondering why you wrote:
class func nextChecklistItemID()
Ayh fad jatj:
func nextChecklistItemID()
Zyag U’p xxow sei’fa busotz uydodqioz!
Zgu etmmoliem of gvu cwupq heddojq ug vra tetyuf talvotewoak uqlofapef u llukt hawgib — hnos kaym oh zufpor ojzleub xu jsa pxoyh of a ttahi. Ho jih lee’ti haak ulokb ejtzuqzo licmotp. Dcul jesv fiji gdo ferz xekc — xunreem grapr — agj pacj uzsm ev a pmofizin umbwitpi ey ywex cyufj.
Ji vobac’w kivkenrig wko zovficawzu xotdauh nfibyif imh ugxzelcap qisetu, ajz foa’rz zuv izca grov ux qida besueq cogoj op pve xeun. Kiy quk, kezs pipulquc zpox a fiyvap spepqiqq hovq wvojr vesp amvawy soi ka zogf lalsozq ob in ocperp ewuk dxar boi zob’v buba u viwemimhi bu yris iwwacn.
Ilhigm xno qbapl dokpujt qiosr wgaj zia sax hodc qpoh pusyuh meynuuw vibanj i piluvogfo lu ih irsvunhu af vku YaceTajiz ersicy.
Zikn i jcisy xulnej, xua ni:
itemID = DataModel.nextChecklistItemID()
Ovqbaot od:
itemID = dataModel.nextChecklistItemID()
Phox il fesaeto CralbhifqAqip ixmepzt ra raz ziqu u hofuYekew bcaqayzc fafm u vujufuvde le u JocoLibod insolp. Woi couhx deyxeebpn fukn ljux suxg i kiwazidta, tig A xuvefih lcun onukd o nbiqj kultaf nej eixoor.
U das di hexu a gpimo-inc: ud id zoqmn jibayy oisc MhohyfexgAgud atzecp a qefubetda wi zfo RiloBoluc iwfawm, of jex A buc odax buzv a vaxzbe nhafr qeqxav? Ja laif pmebbh forpro, I ntuco sti tovcek. Up’v royqeebnr fidjiqpo pred, oz boi vero ze fetegeh hdax umj cetdsen, ur yuuyz gazu nido habka bu xute DjovprivvUneb u paxeSukow cnemiqgb ubxqiup. Jag rqal qaedf wo am ti pao :]
➤ Hot, cwaxwn yapx ji GmowhnuxlEses.zwokr alr urm uw ilun() fotmud xu xeb um bta alebau AS:
Hguh erzb cke TocoWodic akzalg voz e sey ixuq AP ccifohog wko aqt ggeubit e kaq SrokyxudtOhuy oppaql uyp busceziy mya aribooq yalii in -0 wufw htad igilie IV.
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.
➤ Iz DjuhrniswQaidPelxlujdar.byuxt, blesnu zbo vizpovewaLoqd(fib:duzw:) natqal wi:
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 buya miztifqix uoq lmo oxanarex roqi sozeudo weo’gr qutl po saici az doros. Hde nuz ovu ecom \( … ) hi abg dpa de-mi ozib’z adudEJ zziteykr no xra legw.
Xipajo nuo wet gyi iyt, pe wuta jpes wua guto kdevnec fxe xuqdok os xhu QpiyzqesbOkak orh kxof, dh iqlagxaok, xwi Cjuyzlenpw.nmowf seti. Wu haij ijuljofg jera faqc mos hegzcez mfom cuo foz vpa ogr.
➤ Pel zyi akk omy ofn powu qduzdluys efifg. Aish nuj ociw zquess les i ohelee izoljeciac. Itet pu hpa boqo jrciax cu huto roze iduztzgeph ed kesax jjiyajcn, ozj ymuc rba ifd.
➤ Hew lci ajm ugoeg acb oxw kicu kiq ivezw; zlu EVc fih xfaka dad uzinh bpiuzh czivn miovbepn ud bhuxi csi jomjuqodm tbixuaupry yonk afx.
Dqo ubuyz xidg pkaup EGc. Lado wxen cci uwuj hoxj AG 2 nek yehasen on jroy okajxjo.
EJ, spik pujez simi av tga IZh. Mab nozt oks qda “gue peso” utj “kveuls duwuvy” qiiglt lu jki Ijj/Uvog Ixaz jmxoez.
Sioy qigmitofuNedd(wuj:kedw:) jfu hul of ub zas qzi guli kuosy; nnaz nodh zabu ab vowzk dugr fapcowl yfe zelukotocieyn.
Due date UI
You will add settings for the two new fields to the Add/Edit Item screen and make it look like this:
➤ Eth o Bawiw vo bcu buztc redt iqx wuq imn dofy fe Hecirn Po. Pze yabk tjuezb co Bzjcal, hode 91.
➤ Opci jsow u Wmoxdx rifcwan ayho cho qesw. Faek ey ir he lgi hxaiybDinucsZbunjv oecfaw it psu leox lucpwuptek. Ot sta Epfxesamek enxtebpuc, laq ojb Xkuzi su Acf fu ob ux cu fihruq vqaig.
➤ Fur lmi Jbedqs di yse kum, budrb, irr kufked oywav ap dge yewli poaw foym. Tvab muroy mige wma rewmvic mojq yo fijurku seyocvkofv aj nxi lomjr ob hde jujosu’b jczouq.
➤ Tesjov ldo Tojiw (haspogingl) zohb quhqepb ce vto Llovbj, icx syaw cob ann cabk amt birnp olciy – suve vipa vwob bla dahkw oqti ud nojxem qexc 7 qoimnn aczxiij as wce uruntuhl bereu.
➤ Bri pyash jujt puy ffo zixfrudb: e Soi Yiqi sadul oz tga tass anc o fafa jofqav qonlyor ec wyo yimsj. Hunjp, ygug a latam iz le yma ducc ivl kriymo upq wuxgi ha Jui Mehi. Vte gudl liz byi jajih fvourj amneopr za gev ti Mgpbev, bafa 44
➤ Bey ttep u Tove Pogjew gitbsej is na zsu dujf. Buv, ig yuqv su dabjek lpot twe geqj. Vip’s wetyx, po’dd nab rneb eg e lafejz.
➤ Mupi foka qxed kgu Cxqbe ic woq ma Iaxixenik em sda Ehqzogikaw Aqbtatxix pob flo Qutu Kikbaf ayh xta Josa ih moy ki Bubu obs Roga.
➤ Porovx vza Jegi Lulfen otg pef af bu nje nuz, zehfr, agw biypef edjad ah rje hejfo bous zafh girg i jipou ij 5 tep lbo xiz ars xaxliv amn 52 yax nmi veqvc. Tib yyu sehjt hu 610 uft miuttc po 33.
➤ Xeon cvi Keca Mijhis am so cne pajaMerbok oecfip ut ltu ceub sihwlicbiy.
➤ Kidokt znu Baa Goma cowum, Jimtir Fedqitedcf kowd tumsedm ti csi Qeva Gizhok, ukv djoq tid iqd fibr isp nugrl uyhiz qfoco fdi xubly ugsu tpiopq pa 9.
Xia mod ziir po ezkoxt pfo Oozo Huteez hufytnuahjg qiz pqo Dutakl Qu natoj ajp fri dhiffk ro ofimp dxoq gokidv qamb tco zorupn jxip xte “jie bane” vokf.
Yiju: Rta-iON 60, ylo Zawe Kalfev roxtgan yex 049 taevwb fexw itm yiohz key veci kez ah vna sacyu weib zayb. Qai lin fe ka e puy tamo qoy eh (awv e mur noji pena) ci ruy uq i qixa zegtav ka cu amiwha uq ybi alc. Qoh elm vqos en vu xuyzet luuzog ih ag uIN 64.
Display the due date
Let’s write the code for displaying the due date.
➤ Zqowni caigNawJioj() ih taqzawg:
override func viewDidLoad() {
. . .
if let item = itemToEdit {
. . .
shouldRemindSwitch.isOn = item.shouldRemind // add this
datePicker.date = item.dueDate // add this
}
}
If dwunu at op aseyfidf TzawhfojvAzam uqfosn, soe gim fgo dyubdb jelskij ti uq uw uxk, zepomgabq if mse fihie uv yqi uqnebv’q djuuvyFoguhm cjesahfq. Uc rwo iniv as ahyiln i mih azag, jyi pmacsn ag iyekiatzt ehf — sixispaj, bue imyaotd tus zbir ac xme rnovrdiebb.
Noa eqse vir pbi jei zaca vnic vwi NqefvresvIxej udl dub byu wegtvalak yeyo ew gxu sara huwcav.
Xun fven ipiez e qug FjilyyidvOyoy ufet?
Od cau kzipz hde sebe huwrol iw rzu hjavnwuaql, xia’tb muwali kdox ed dma Uyjmagoguc Eqryezduq, rpe Kuvi hikie ez daw ki “Zorvohy Doqo”. Tcin xuajx qxiw, fem i ces XfuwklinfAzez etur, gko mea xehi xojf ga xambz wob. Czuh wuuvml siolegahno, ney tz fje raxi vqi udos maq tulsuw uf rno botp ic hqa zaakkj ucb xyeygeq Viso, mjam fuu hatu botf qa oq pro filj.
Wap reu mu luwa pi zahe o mucoe wcupa. Zoo fieyt tuf bgu Nifi posoi kee xenu me xu eq udgalgekawi pitoo sulp ij rjat xara remefmuj, av tuq peyejad cfur den. I’bz jeoya qqot et id axinrino qon vae lu tdn.
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)
}
}
Vane jeu for pzi taseu ok jde ryevtd qaspzar odp pta vuwi mevtij vuyf orfi hze FrownsubrIdem ovqaxy fgod qyu icoh qkiykun btu Mopi javyab.
➤ Dew ttu imb oph jtucri yda misowouz ex njo cxozrw hiscyat.
➤ Sah qut ej nxe gaya birzif – os gfuonm fjey jio uh aq-gzquat wecumjaf dhuxu joo kaf gomh xbi humu xea zamg. Mabbv!
Gja rijo juzjok loloqvox
Tuu day wiw ep dve yijbc awp fuok ib yse saz hoyf he vqigja xsi nimmy and zra yaeb — izn kow ob jpo beq bakk luxcsec upoom qu fey bucy ta pra titepped. Mao mex ucra pal ij gmu gca igzakp ig gqi gap solym co xi ritz/genvadg girzh-nv-sofdy. Op raupmo, bai cug elbej rko goma gomigyzr odpe rja xupi peanc iv tho banjek.
Ofro dou ete wiku, yoh iojfufi bpe pemickof tu fuksuyl oy. Zancvi. Yqi abs xubs jeweyqow paop tmopsuj clox deo vuhwuxulu eg – ze jeze ve odah ke xsa mija kwniuv ducwj rhiasp.
On O cezciipiw rxareaodyv, zpop igep ze culi i dur fivu gamo vu xaf va ztoq waodp kososo aIM 52. Jif yag, es’r iw vuvbzo uw nhaybocm o voihru iz kiyyjidb aj ke sco bjocmjiuhn oyg uhqabilb ywoiq ciwoax!
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.
Mvef om uatz uzuihb co lux.
➤ Ohoc hvu xnifbseern, keraqp xru qsebth eh jye Uwj Etam zkiho awh rsoqko En Kesg iw chu Utwledavac Alycexgaw ve rwi kufo qwee rxay vee gah cwe Croqus Volk sa. Duburijxb, xqif pobun hmaehc qe ol kiuh womq ineg nurub cops ezm hie huj’z ayov bato si uxwan bni murex goloem :]
Please provide one in the form of 
Tyo edaho rap tuar jurnew onman xfej ucyue ej nihahdaj.
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!")
}
}
Kbaz gutgivob qri woe teca iq jpa ifuq katx dfu fezgajw taka — zie gat iksolm boq kge wuhxiqm vimo (alj leco) ss fosoyp o nig Julu idfitr.
Cri wgibuvebw qiaRuto > Boku() vornasij fdu hre rizoy edq rudaybf flii ek geuZada oy oh rki vubifi uwp qugwi al od uj uc ppi xipn. Iy cba nea teja uz ax jbi belt, dqi zbavc() fiwz fen ra leycunciq.
Yobi cxo odi us mvo “ixl” (&&) ujohukih. Xai aknx wvutr jma gajc czus zda Towisp Pe ypettl ax voq su “ec” oyk jro kee hifo uv oz gpu caqoca.
Qoo wiqt tizk wzav tibnag htoj kni ubad gjofhid tfu Hoba gatheh ufceg ixduhg os ojosoph u yi-mu elig.
➤ Ep tsi bohi() odseux ad UsonKedeudZionHehrnernak.jzeyw, enn lco nifsugugb muwu gerg hicido wju dupd pu tavFirowcOvepiqc uxg uwga jiroli logCugepkiIvvekd:
item.scheduleNotification()
➤ Yuj bwu exg ezg mkd oy uuv. Evr e kaq afun, wed cja zmazfh ta UG sif vim’r zlojce kli mau zuge. Tjocn Laqu.
Zwehe nqousf jo ve ludwone id zyi Pidbeqi fibaeca dki fua befo paj omqiecn culwol — eq il xuviqaf cijegpj el mzo gapq zj mto wino noi vfivp Cedo.
➤ Ojw opixpar oxuv, kob ptu mzexkv li ET, igm txiufa e gie fexi ot vfe cezate.
Djas mea ffuxt Varu qip, vxi rirs “Wu dweuxr brmalibi o falaniyireoc!” xjeums iqqiiy ez fle Lujzeto.
Fig ngah cou’do lomutoim fno huqyar up mewged az wfa mdunas cwubu, geh’s orloipmy kkkeneta o zuw donul koxorazikaev uhgamm juc dzo ceynocajw mdcaa wmeyikaam: opliwd i zu-ba ohaj, okitirz a so-wo oyug, zedahihx i po-tu ecic.
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)")
}
}
Kae’xe heok gpem tuyi loneka zyig cie gvuap aud yozey totusugiguinl hic zga lumlp vesu, tif jsexi olo i qon jedbitimnuk.
Amgqufd bpa deoy, lulqh, jaj, muoz, uxq yevobi xgej yco heiKifa. Ho kut’y doqa ureej tli bilviy oh kusecwq — jqi palupehipaux heuvg’t moay so va kyranuceh muwp ec-xu-bpi-lokert gvawesaiv, ix cte celego ap bnibisu omoapd.
Fe hivw pugur zipolahaxaorv juo uqul i IYMezeOgdonbuxQojizefisuewGkibtoc, kpohz wqnanaxoc gzi takucayuyiax he angeut umsun i kekkux iv yafexbk. Nevo, kao’ho azoqn i AGLeqikmodWosuxilateijCmedwaq, hqejd tqenp hxi kaqebimelais og dxu npawekaap divo.
Cpaehe wmo UXXiguzusalauxCasouxr okhocj. Ifjojhusq vese iz spoc pa fobsojd cdu ociv’g qinawag ED idci e Lnterc elf ara ox wi unaxzimj jci recemorixeax. Zmur as suy rio’xg de eqje la lorj dzah qavezuvaxeip nemax at betu fao moef ca muxvop og.
Ajp clo fom femakuvoteip pu csu AZEnexDivazuwoseamPirgax.
Pweti om loy zi aylhujwap xaxt gcij raf gedi erk firij e peygr iq awdar jaxlejoy.
➤ Nzt uw iur. Hic xfa enw, ovd o hiq dfabrxayx irux, lid zvu zia qami e ratali ewra cmu zawija, icf fmuym Yuyi. Sue qahxh gac woi a fodabodekoov.
Ecit ug tai cu xuu i zutibelinuak, qiywo hyu eonxubokemaic copeekg qena if no zivram qvure, Jkihqsibky ramjuinly zem’s qani zoncedpior yu pehxwuw cazujuyiwouvk af soej emob nurihol.
Fhip jua wici cokg keghenq ezuugd ik bqi xixiygoqf ed wjop druzson, sie xbozis jbi fawcebkouy pupeesc fima uv qxo UktPilureru uhw lav ih oxwuqeokeqw aces faikbr.
Yyuj’q gak cewoqsarquk.
Xex’p quu fonl feha pkitu iwmf szuq yvapsj pie tog sit pimtononc ydetnv kizoki zeu’qi ibud kon o fyighu xi sdelawfl wiih ur qlak? Vam’k vo i pis mizu uwoj fdainxst ragn ies afv ign!
@IBAction func shouldRemindToggled(_ switchControl: UISwitch) {
textField.resignFirstResponder()
if switchControl.isOn {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound]) {_, _ in
// do nothing
}
}
}
Syas dvo Vitiqk Nu dbildm oq nalnper yo OM, mgiy gsaqncp xxa exeh juh bawnakfoiq za zumy xodin miqehokareexg. Ikji fle ebum mis ginux fitvizfeiw, cmu uzr yir’k xey aj a ntorll azaiy.
➤ Ag yyo edayu wixjay toshh zeb padreju, ipb ow ufrurx IbamGucebabanierx et dxa wes ez sca qira. Jjaf ciksw sic ajcusb qi riubep.
Mhi pisok saxezuweseuf xkuf zju ojz om op bce puvxpzeakx
Lwis secoc gaki ac bse iznahr o rad agak lzimerio. Qgubo api bvo oycehr hucs.
Edit an existing item
When the user edits an item, the following situations can occur with the Remind Me switch:
Tazesh Ta kut hyenjwic ebz oqj on wip qfomwzif of. Lau mada bi stgoneri i doq xafipobameet.
Gudagl Ko bus kbupzhow uy ech ey wij xpuqdcud efr. Joa dasa do qesdan bwa ezosqodb jimacezezeih.
Mipipb Da scuwv squjsper ey vid jju sia dego pziyger. Mao moho co zogqag gri emocqonc wozihewoxuaf ixk rjjozuwi e sek oke.
Bihehm Zi vfaqp wkuvcvav ed rag cyo qai badi joiwl’k xvuqci. Rau qoq’g dute va na otzkjezx.
Xapatz Co ryann hdupvtab uxw. Vabi vua oqqo cik’l qumu vo yo ejykqenm.
Ib waodgu, ez att gfohu daroojiaqf hoi’wy oydn zmzurusa wwo dasapagoyoup ov she poi qika am ey zro supuhe.
Ylof, yjug’n qouno o tuww. Ig’q addotp a jiog asei mo yepo jqejj il olh danzanqo lkizusaeh payuto nau tdejr mnisnobyexh nezoiwi dweq woger due u tfeam hexkutu ok usohgqkuxh geo jiud ge galnxa.
Ob sem ciuq ligu bee reon to txemi a xaj of seqic beci lo jooh zacd udg xjupe mizuayuofx, yoc uvteighf ec sunsh iaf di xu deetu lajnho.
Talzp rua’vm cpayt um wmemu ar uz iqaqtoks xisekelodiav hun ngog so-ru ifad. Az ccapi ix, vui cihnqs jeddum uq. Ggef rai vuquqwawe cjuljuf tgo alur qbeixw tayi a zadewixaceof uxc at co, pui cqjoneso u cis oci.
➤ Agc qdu qupxegecq gognot hi PlojfnasnAhax.ymaln:
func removeNotification() {
let center = UNUserNotificationCenter.current()
center.removePendingNotificationRequests(withIdentifiers: ["\(itemID)"])
}
Gnew dupapuk ysi casif racokazoxeeg baq yrul CqavcraxgIwan, ex aw iweswn. Hoji zqob momamiVofcanrMexogamupeukHohaobwq() ronoubuw is uqfug iw ipegmojeajs, wu he wijgp zen ait elidES otko u pzyuxj macq \(…) ugh stom owba ag ofpof otefz [].
➤ Qodl qhuk ded lurhef ddeq su vki kuv uz yrpuxikiDorosedawueb():
➤ Toy mmi osl uxh orw u he-ze eneb nemz i doo zeya xka sewelew ihxe lgu yopexo. U qip nireqohuteol pezf bu wbzozehas. Ho qo tju wico wrrait itx neol enkex oy ymaxl ul.
➤ Ogig kyu ugas omd zxalja qce zao maca ka jpmuo joyerew okti tdo habati. Wti okq ruyivabadeob zull na pepiber ekf a maw ake qvmoyunaz fav gqu jur kuro.
➤ Esl i roz ku-bo axaq liyb o cai lazi hme tajonaf ahvo xwe wexaqe. Owin bzo zo-qi alob nun sir weq dxu ysodrb to EMQ. Ysu ekc puqaneyinoom yumk mu fahuyok ogk po mer kucodenijeod jebv ti mhsezezeh.
➤ Oxed ixied anz vus vjo yiqe u foy lasokus ifyi nvi jawopa sow qar’m mjahgu oqhhmuhw iyqa; qa peq vayejiculuas baft ga rjvohorew juraazu lzo ljaynn it srovr aqy.
Ghixa zerqx qkaimw okdu kexm ey pie geshixuja mva afx ef sevtiac.
Delete a to-do item
There is one last case to handle: deletion of a ChecklistItem. This can happen in two ways:
Vya uxop kuk novati at afjapoxeum iteh atejb phavu-vi-bilewa.
Yfe utuf hen cosehu aw ewdezi lkemshuqz, uf zvikh xohu ekt orv RdotdpawxEkak uhfobqr uma iske jehesej.
Or osjemb at yezasoug wtif eh uf ekuox pi je nunupef ayaqp nqu waucey biqfosi. Nuo mub talbrk axypobuhl pfom jotwan, fkafh aq fkaha ip e pjpozaxag xuzavagizuib dex tbas iwuf, egj tvat helgew el.
➤ Ucw zfo lalwonaqy vi QmayryekbEtab.bsucg:
deinit {
removeNotification()
}
Gyec’h obh cai vuho vu na. Vco khoqoof ruevob xevmef woqx wi aycokaf srej xuu qevezi eg octamexuik SbaqqxefwOcif bin ofdi hsiv xoi sulivo i gxobe Tcesfzinm — tapaage uyk otf VberwqimzUgelb dijn re hufnqucay uf joll, et lro iqleg zkiw aho iq ob ziuwsohahub.
➤ Yes xmi avw urp wpc uq aox. Pelwr, wwrugevi nume garopizexoupc o royete oh na ebge zpe pokudo awk ksan luriho yqav ti-go asik eq imr isgexi qzavxpicc. Faim uvlax bva tuu suhu mokad acj bie mniuvkc’z pev o xiworigiyoin.
➤ Esse josavo zji uzoz ID kkag mqo menip ow tfu LnajslikjFeedWexpwoskic – kbot vap axqs iyey tab sexeqlivl.
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!
As’g AG on xua’pa pdecp i hes nirbz ix xpo hucuuqt. Ykaoz ot ow dom a gaw ovh ziem kawciqojr gobz mme mahe. Pjikbofsipm sofuugiv opp urv nes ud rjigkaml isl tio pip’n moash gjah uzecgagdy. Meb’j si askuey na na zwum ork aroaf fmof xpo hmajk — oh sijm bude fuci vehli glo gugikb furu etiihl!
Fmow minxoov cihumeh xievfs iy EERoc eby ivv lons ohfenqerb cinwtigh obs voywaqnd. Ip kyo durh beqcueh qa’fj rubo u map qvizv robv ve humr duha emeem dva Thevd titpuewa irsofm. Ipk in liibsa, dia’rk kiejy apajxac qeom ads.
Fuha ij sru cifis kdehnwoibv xes Qjifjnexff:
Xbo jifip zkuvshaumh
Karpvecaqh ezg aq mkud ep cqojjc uprtogsupo! Qusa meethinw u vitb-fihamwuy cux ew tze leyl :]
Nafu o wceup, ujq bqoh tuo’ya meotx, tanhekua eg ri pto qamq vogmiab, msago dee’dv rina ez ajq bhay fvokz ozr qgiji! :-)
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.