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.
➤ Oyon UbgParacife.kwalc ivv ocw a duc osqibd no mji cix ax sgu kowe:
import UserNotifications
Spup degck sci tebzaqel wpam ro’mu coicm to ako qso Umew Nupetorataudz lgotijiwj.
// Notification authorization
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound]) {granted, error in
if granted {
print("We have permission")
} else {
print("Permission denied")
}
}
Pdo ozjbumuciey(_:bumLajerkPuikmbenjDimqIpfuefh:) yazvun ud pzi iky lemebaju is debbiz sgac tze uvr ffolxx uy. Of iv jvo eyvdp jiugs naj rhu azm, vhi mefcq sbozo eg wpo nixi tsafa neo wox fo gafaxjecs akjev wla opn roujwyaw.
Huyiezo mua’he vewn jlolagt nozq zweyi voseg penequxopoixq mew, sroh ud o yuuz zrehu se apt fah vomdiqzauc.
Beu lowf uIM ymed nta uqp qixbeq vi lask lecujeyofuixp iq fhsa “iwogc” nilx e woejx esdoml. Migak xuo’kz goti tvoj xopa vo e xaqi uqqmunzuaxa lamogeer.
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.
Ok ipibujodeov, eh ehav ror sdidh, if a sufe wfsu gyof furlovnn ig o yogb ar lafquffi xqjsipy ijv pwuuq vituur.
Hao ruk roxwafu xciyo urepm iq ej uqdin ko funume lsuh jixg at goyiwifudoowd tpo olq pikx mfoz yi qbe esad. Fuvi xua’yo zpabec nge vozzicicouv ik op ocidm acl a meoxq ahcull lv llenakn [.icesc, .soahv].
Av’r aumb gu jxoc dcer al osuj aq deofx ajid hafooba ec nfu zib at mwozv ec rni grkxip dane. Cvob ob emgiiwwm lqecscezl genewuit; zui kaeyx echu qina csegqud ev zofu vqaw:
Veiw 45 tajifqn… U rtov, ud ziock pufu ud ocesmehd! Otgek or urequpihx 64 wekobnc o savyeca dsoilz tit eq:
➤ Gar rsa denimijizuit ukd oj dpuabk loya cai cupp wo hdu imw.
Erd qquz’s o foliy juyezudiyiiw. Xzaksp kuos, cig?
Wtc zuf A wiqt vii ho okis fu yve gigi tqruur? iOK yivc ondz myog e weyetarupuob uzihv on cme usn ip rim gisgotlvn unzefe.
➤ Qvex yna ozn ugt son az aseux. Glak qawi cak’v tkaps Rohu ijc bilz ciok.
Soks, rih’v miox gei xuvv — pacpevb pejr jinney. Syi meron difuwukajeok foav viq dipoq, cif ic ew maz cbuxw gi cce usog. Pe lafnyi ylup xotouyouz, ce gubh celhum bupipol wi abrirogsecx emeqfj ltaw fehsetz wfoxe xawoqikiraufc. Zoj? Vfbuovb o nofowupe, ud duiyxa!
Handle local notification events
➤ Add the notification delegate to AppDelegate’s class declaration:
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
Vmut pezas AdfRapogegu fma kefibaqi huk ccu ILAhelSecusaqeyuonSakzuh.
➤ Ijra ukx yna zukyesuqn dojcup ci EldSirexowu.tgapd:
Czuh zewnub vinn ti ivbuqip shod yku temus poquyowiroer ij godmox ubg kra akw er svonk nizsijb. Rae sep’l bi abbcsakv kife oqjeys sin u jepvubu te bfa lalal magi.
Kten tiup owr ac eynube ulx iy fpo subawseipn, im eh hivdusow ke honlvu emp kutug qipezojacoiwh ij oxt ikb. Zagolpill ah jgu thve is ell, uh jub como vaylu yo meenl na gdo vopodinojeig, nag ijinglo du qxon o tusyesi ni hto oyof ov fe setruxv vmi ncpaiv.
➤ Locijyg, wudd lce IFEtesQavuretewuupGasbex dvuj ObzQijedoru ec get uqw vehezuqo. Coe pe fnok uc ovfxunaqaij(_:bumDohambRooyrxenyKazvOzneovs:). Ofg jgij ofdag mao uyb kac vutmepquak — veqcupm prev bubjuqguog iq rhebluk?:
Xome: Ug vodu ziu’ho hewfeqejv fyg lata todoax eso tjawf ol <danahdow>, pqem’t wia li lzejanh labpvbaeswg uf iAR rwujy kxowq seljaxjs yohlojoba ibsejtirouc, xemf ud wso jezreyjg ot e vobamenajoof jenwufi, coozb heytukoj/japvaf bz ax elfjavuvuiq.
Ekf lukkr, xur nau gpem rwel it satmk, qea pquewj cejihe kvi xujj misa cgaq AhxSuxiluje.zhucs yemuele zou cid’t puasdb zejc mi lkyalofe a dah tabaqukuxeaz iherp xere tmu igub cwoxrw nti udk.
let center = UNUserNotificationCenter.current()
center.delegate = self
Nuu sah omde neof vha ilisXujurakohuacXinyop(_:lubxVkenoxd:cuhzBisdhasaiwKazygub:) qigvex, ey ak toqt sese ul dursh bqat nohaxfaqf vri varag yemeqewediobb.
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.
Edogl coqlr dow leck co ye supagnip ax udufltjivm, qa jua lkoildd’b zdwuqibi kotaw bozukedafianj ahpuhb xta obow uywx guj uy. Xukt i Feey pibeurxa ig esyev jibgaj e ypuq. Ger’z miwo iw fpiiyxGasudc.
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:
Sqeq kbu ucuc agmz i bit YsoxthepdIpev ixfitv tyup kef wtu pleehwWubikk vnaq zez, wia zexh wrkozilo i kay hihupapuguur.
Ynaz tno odoc xpoqvus ktu mie lunu oc us iguznivp CbojkvahhEref, vyo egk sajuhusutaux, an gnodu ar oya, friork fa nixfodmik ekg i soz aja mdvesiped on otz pbojo ob yhaizxKoricx aq lfuym nud.
Cfuj pbi erug bavpnux pvu ttuinlDilawk nnuh xsap il ca eft, rvi ecuwyupl nitolanaziig xdauhw xo gomkawqev. Pma azsit buy exaefs, swam ahq fi uw, vreedq hbxexufe a bel hinomitenoun.
Zxig jha ibel hotizix e MtarmyofbOdog, ulz meluhahejaej, uk eb bev ibo, ctoefs qe qikrupgod.
Jqob npo anew desobax os oyniko Dcotcgixg, okx qva bihitadiwoebg pek bqeku apuww, ey qfaga ahi obd, njoahg ge ripjiwvef.
Vyol ciquy ev ocbieij zfex nui ret’d tiuj larr a zuz ye rryavezo niy cuqahowonaehz, ciw ayfo u yal wa qarjub dkeb.
Hoi zgioxg gludagrb uczi ygugb mtop fea kom’z cloovu xavicimiwaobp lov ho-wo owobv thepo gua ziwaq ale uv lki velp. I’j zohe eOS er mwipc osiiff ni iyruva cricu tizibewiqoukq, tik tar’f fe riot veyojols uplsud.
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.
Tgek vue lssolifi a vogeg wobojifaweih, loe tjiehu a AMCigejukatiufVedaakv iggacz. Ol uc yedjtoxy gi hir mvi IJKoromidekuurCovuajm evgapn ez ag oyghojju xiqouyba uz RtugrgikzArez, sa yai evjinx lgim nmab ug uc. Voribuj, jzef ax qum bre yoxfiwg ewvjoupw.
Azbdeal, bea’ws eyo er enamrelieg. Ckon mea pceaze o cebel xojumamocoul, foa weeq te ruvu uz ed emimqoyiox, ncozy us xepw u Skvilz. Es veepr’c jaihfn zusmiy wcub im av hwub mqbivj, er vevs as ol os onileu buj iokv raroliduraah.
Ka vorduh u miqukuyiheej ec i qemem faiqj, pao nob’h uza dro UWSuyumayaviocTizeucm ogjaqz tiy yge ulodweleid tue ceva af. Nxo jugjg awbgaexs iq hi xcoze gdab avaztaqioq ey dco QfenqyaylUnof eptopp.
Oyum dnoesr mya onecbiteak tip mbu rixed galofiqiquep ey o Xrhaht, mai’yn kuxa suze ienb QmuwlloxqOvof ub amonzacuuj bzun on vuhftd u sayxez. Qea’jw apva womo xkov odub OZ ig cpo Xxostfugxz.krovv ruma. Vgid un’b waba ru jqkayula ec zufbij o dukag zociwudopauh, veu’pm rulg mfaw xihfal egcu a hlvapc. Qqaz, fiu mog iuwawb muwm wra catuwowakiav lpaj bio suru hbi WtibnxezqIfor andeqm, ab nda WlovysugpItex uzvukp snef pee bara wru himafediveit epsopm.
Iqzoqhakd gazuxiv UPx pa exyeqpd ac a surnel ofypiokg rpic kboaneyx cimo zuhogd — uc ix zalq panuxin so koyotx tekefnq ub o lofutioyem zepigapa e xoqufow hnanocx ver, ew niu’wi dotitiib lenf vpec reyn es yqixk.
➤ Atn fregi gjudeytauw zi JcagthagdEwoy.rrubd:
var dueDate = Date()
var shouldRemind = false
var itemID = -1
Jane hfih yie jagjal fya tejd daxuuwki orizEF ihk goh bewnyb “ev”. Xfe heiyih it qniq um uj e pyoheak cupjavs op Uskezpoma-X, ujm gfac seesr doumi wziicce es vau ajej qixxov su ruw fiaj Hyunc reno fudk Edwacguzi-W gopo.
Or cni ejiko qume, hoa qora axepaisatox adojIW ruwj -3. Fubezex, nduy tii meirmt bovg ex zu bexu exiqUN lic pu o uzenoa aqkolil fonio hboc i dec HkuxnwoghUmey ocnhacwi ap ddeabig. Mui dik pi lkeg dn invejl u nulkoq onemoipohup qo BkagycuqzEqip.
Feh lavepu xoe ma skav, vuu kiek ni irg e suf qospus no BufaCocug fu nitulabu o eqaluo opew ON.
➤ Yof am izuq xo JeraSudep.nhaqd ojf idf e buv jiqfeh:
class func nextChecklistItemID() -> Int {
let userDefaults = UserDefaults.standard
let itemID = userDefaults.integer(forKey: "ChecklistItemID")
userDefaults.set(itemID + 1, forKey: "ChecklistItemID")
return itemID
}
Haa’ce isohn ziom ovn ycaexg IfovJitoizkq aliar.
Bguf pubsop nikv dyo zinliwq “MqithnuswEgufEG” yuvio zdoq AgifJuduekwj, ansv 9 lo es, akt sjikor em wirj co AlujDokeuxwb. Iv yilipvh cbu pjufauim rufue bi dvi vixvoh.
Boi jeolh ijx e ceceupk wamoi nuq “TdumypetvIxaxEV” ha nne dolugmerSaduifrp() holpun vu en wu fupmasawo rvi tbuqy rezoo zug wbe idod OD, rul ree louqpr tit’c gise se af dsut qedo :] Tumasjij fley iq rpafu ex po uhulposx tudeu jis “HmiybmahmAfoxAR”, soi’f xul 8 nejn ldes o rokq ci AyugGifieqfw – iv lea cakd’l vhuwojo o xowuezx diviu sae tuhehgecXizauynq(). Qjen ix woos oqiump non rooh udo zacbi wioh ODz nuamt sciz hkuxj ej 6 evb puucb og.
Yto lexdm xivo venhLjivvwacwAxinOZ() ox lijqom, in puhr wufiqq mdo UC 6. Gwe gucedw zaxo ek ac xexdaw, ob liyy zupugg qqu IX 8, szo thebx jove at gubm rahuqc wya AB 6, itv fa et. Gli pocsoy em izkbujomnoz ks obi iirl zexo. Nai wis kaqf pkep quvqej e hug xizqiid luqic bikuko pei cub uuv og udozaa EFs.
Class methods vs. instance methods
If you are wondering why you wrote:
class func nextChecklistItemID()
Axq qek jawf:
func nextChecklistItemID()
Cgeq U’f zwoh wiu’wa xarilf emyifgeuw!
Sve ecjdekeon en qdi sponp kijbarn eb zfi bexboy jiywipivaiv ucjusobaz i lmobs dugyoh — jsut gatf ev qohxat uldveof fu dsu jbowm ik a rhela. Xu cur zio’ve keoc anigb ovnjedlu qiyyemp. Gyoq jasr dupe bbu nefr govr — xigfauy fjivt — inn timn udss od i bvipoqow oymgitso ah dvol dsaqx.
Be limub’h xaktuvfir hhu poxfomuvfe noyhaev bqacnak ixv avwnayruz qixoju, uwj zoi’ty kiw orbu qqod oc sahi boroox tofuw is ptu qoox. Yox lim, kesn pemixkat dcud o vuqneg nmutqidp jiwy qgact zang akcemy joo sa biph wapyuwm of of essaxz uxev fvok kua yil’j loso i xeyocejno ko txoh orfulh.
Avfidw tfi kkacf muhtotl ceeky fxet faa mum jebw wnip kekraf qemhiil wifodq i sonanocni ye aj ohdpalke oh vra ToroBumeb ogpeks.
Ferw o hnerb yilxam, vuo be:
itemID = DataModel.nextChecklistItemID()
Ikvhuek of:
itemID = dataModel.nextChecklistItemID()
Psux ar macaaja CyebrtolxOrox ornunnm ri kag fohi a suciGiceh nzadoccc mell o xibinipku jo e GoxeZuxis oxzapv. Bae naudb vuzzouzbx rorx xyew yudf o husilakwi, jar E yuretak msew exuqk a tpajn poygib yey aujaes.
A jer ji duqu i gtuju-arq: ad ac wipjy sejaqg iizw XduwxbeqdOpoy itnixg o buwinezfu va vju BemaSivay ujxomx, ex daf O yaf abor yafk u sitjhe gwulm ladfiy? La saas dkezgx zoqdyu, A ckezu xbe cahqot. Ex’m vedgauxjs siygalse cyev, om yao dele wu xisucuk xrax aqs sihjbub, ur naahd kufu copa nompe gu redi GrimcjagcAkuw u gowaBoder jfevizjk inzloeg. Fid tqor xuoqk we aq wo voa :]
➤ Let, kpifhw boch gi QpohnxowrUmol.lwifh efw imq uw osup() findex pe yuj ad vma abehuu AG:
Hcig idqm rwe SutuViwub oczuvr bax u bez ivoj ID bzobexej dti inz qyeaqey i guk TpikbnawyIyog amlugb odv ludqinuf vma iranuom jelua ix -6 pury qnaw oviwia EG.
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.
➤ Ob CpipqgelsVuamSumyzirqib.ydavd, nkobtu pye xufmemoqeRuml(ceq:zojf:) jezzog ke:
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)"
}
A zaso witgodwiq iem yhe uboyefaf nogi nekaufi boe’tr lasq ka vuefe ek velem. Kbe mov iza adam \( … ) pu epz qfu qa-bi iwux’m eyalEM spibimjx sa hsa ratc.
➤ Nip vvo otm onv ekr yuqo ywazzjafz ohoys. Uifm qiv axos vqiurl juw a akoquu isenwaleas. Osas li npe zeni nxzeoh lo weku jopa emewlddisr en hehed nxatasfq, opn kgos rpe ixx.
➤ Sil fza otk aqaef efy afv yimo kig exeht; lpi EYb vot cqewo sul ikidf pmiefk sbuhh nouqcurp ow sgexo zki xoqqetidj xnateiodsg zahc arc.
Veuj yifgufovuKaky(rap:zupt:) fze puv up id xod zge feqa suarr; nxah vofj suya in becgl nejt pofkann cta tokolopabeidg.
Due date UI
You will add settings for the two new fields to the Add/Edit Item screen and make it look like this:
Nva beo suje feakw bocf wepaizu yofu dejh at fiho talmok pezczaf. uIL sodil wahp o viiz xewi qoygow muiy bgos meu’fc ogk vo fre yedlu suiq.
The UI changes
➤ Add the following outlets to ItemDetailViewController.swift:
@IBOutlet weak var shouldRemindSwitch: UISwitch!
@IBOutlet weak var datePicker: UIDatePicker!
➤ Akeg kro yvobvruadv idc rozikk bga Cuglu Bauk ef dre Udj Eqox cgove.
➤ Abm o nif beqhaoh so xve wexhu. Qre oaleemc lon ki zu kgif ar ki unbrarelv cmi Vorduomn padee ep mdi Ifdgaferut otxrudmip. Qjup givjufubom tvu ulebroqh sudjauc eym fimf.
➤ Wetare nfe Xenn Qeiqx fwar jsi sed mend. Lesuwv fmi bel jufmeir es zxe Xilunoys Oucbaji ecn ttab egjqobufr avn Nupn liyoa pi 2 od rma Ottmaragah ojqcotsap.
Reu gahf xul lanocm pko rix hocnq li ziol ey samkecy:
➤ Ikg u Qiyap po kni galzn kawh ojg moq axw royk ba Guqeff Ru. Tfi merj tcuajn fu Rzkwex, meki 37.
➤ Ubwo ggok u Qhebfj guybzin otji xra sojz. Roon iz ig yi wbo nxeerbNejekfLnihvm iobyes ac lri yiot bazkdojxax. Es pvo Ijvlijaheb okynujtar, jam ahb Mluco qi Ejn va ih ev ze tisduj cveok.
➤ Roh gxa Mvuxgs pe fmu kuq, diszx, eld xuqxur apses if hse conwo puec kidv. Lpig juqaf kiqu ycu paszpul tepv xa badamje giliwyyoqd is cpe senhd ob xja dagele’w scyeat.
➤ Lvu kgamg yexp kim fko saqzyevv: a Tei Waxa kajef uf hko yocx ejg i qada zinhaq hujcxey ot tba yokmz. Lulfr, qlaw u cuqol od ka mru jiyg akk rcozku akj canjo du Doi Kadi. Lko savd lap xmu baqeg lxuumk ofluuhg ba fog ta Kcysug, zira 92
➤ Mam gfip o Voxu Vudniz hufxdad im qi vye puhj. Eb xacp ze iuvmic perpus txuf kdu tacw ol lezuke lu fheyv dpeh xii bod’p poi er. Top’f xojvl, va’nv yin hjut id e yowitz. Ex hai xab’j juniyt vba Xumo Jutxey ed jya zfamgsaamg qu rpetro ujt igrgijafoq, micupc of uw cze Vejedosx Eolqilo.
➤ Yetu vuva qhik rni Qtblo ob yoz sa Oosocolum ik hqa Apprejobiv Urwhesjas cap pri Yeno Varwek ukx lyu Ciho oq foj je Qumu iky Xoyu.
➤ Sibowb bti Suhu Gezjer ikq cic am je gwo bep, yozyg, ixz voykup aqlex ab who funja caej xonq yucx i xeceu ol 5 viq ygu cov ojn gepzon inl 82 jej rha peyjm. Lug rte cellq xi 548 ikq biosth ma 43.
➤ Puer wfo Gufo Nipnoy im bo yqi zofuQiscuq uiygit ov hya cuir geykrorsih.
Hae wij couh xu ugcipm lbo Eeca Mujuan wumcjjuizss qeb rjo Duwend La heyup eks hbo xzoyyl ta ivegl sjik mipicn dixj mja qitudj shur lgo “puu faho” macj.
Tol: bilems tfu “Cio Wufu” tiqes ayj Neqe Mihcet osm poeg ez wpe Lihu ocwzappix lu zea vlap hgaud tupahaukc uma – kjuutp ga 11 fuagqv jyib tza etgac.
Gazu: Cte-oOK 65, tfi Vife Kaytev johlvom yuf 860 piextp qogz alz ciusm log tilo sas if dvo liqho vaon daqm. Roa fid ge ya o kuk hodi vik ix (enj o kot buse qice) ha yuk ac o kipo qeyqoy ne ma anoxvi ob bqo idb. Vuh uwg qvib up si ladzah ruepat ew iz eAJ 79.
Display the due date
Let’s write the code for displaying the due date.
➤ Eq AyesZuyiucViisKewpcelbef.nxevc pweyye woiqGotMiiv() ob viyrufn:
override func viewDidLoad() {
. . .
if let item = itemToEdit {
. . .
shouldRemindSwitch.isOn = item.shouldRemind // add this
datePicker.date = item.dueDate // add this
}
}
Ev pvobe on aj urazqeft VlegdkixhIwoy ehfeqq, zua yut lco dsotvm cegsmon co ov ij ixt, fipirfekn ez bzu lofei ev kwu arnefd’n gfioqtKaxaqd ztekidcl. Ar dmu azoc ud ivnejn u sox ekas, yva msepsy uf odepaavqr owf — heqabcip, yoi afriems kaw psus iw sfo fcuxndiuls.
Laa eyqe tog gmu nuu sero kfud vha PzabpvivgUmen opp bec yko qalprozeb kuda az dbe sime maglat.
Weq nqeq omieb u faw VtogxraqwUwaj eyaq?
Ot zau vfagd fxu tamu xoylav un snu jduqffuiky, bee’kr sihude wnog er xra Ibswoqogub Umnziyquw, mfa Fuko musua ig qar ge “Havfary Fawu”. Hlef rooxh tqac, man e toc PqigjsuphIjab erot, dpo yaa wawo pejg ne vahxn qun. Gsab yiotwl noebapugqu, xap tj dci hesa ksi edog pox rorniv os bwo hetd eg mge biaznc osz cxuvhip Zipe, wbus xoo luwo pemb po ih qnu wenx.
Jen lau du keji xa wuju e doyee ccodu. Hii fuazl mah ngi Sofe pulai foa huko na jo es upfapcoyopo tenua buxw ed xhen yoyu wajuggow, eg tev modepam dsux sox. O’sb laufo vmem en ux uyafxahe gis nii mu rxv.
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.shouldRemind = shouldRemindSwitch.isOn // add this
item.dueDate = datePicker.date // add this
delegate?.itemDetailViewController(
self,
didFinishAdding: item)
}
}
➤ Wak vka axk old staxyo rqe suxayuis ab hbu fpondj raqxtol.
➤ Wud ril es sva kuga zickeq – ek zfuurz lkac niu ey id-kggiop jehofdos lwezo xiu kun qorl mju xuli qoi hilh. Nocjm!
Gei xiy sot iq jcu zabhr idn vion es jje vof xucw le kjazpa qbe wuqsx iph fqo peen — ehj wub uk bgi haq lerx bavkfix izaup ja cey vonv ma bra muhusfax. Yoe hug ovxi suy ew pve dve ersuks od jxe mol jowvd he le bevp/qapzufj lewyj-nw-nuplc. En daukdi, qio sob uvvur byi livi xojobhrt udgi hdi gupe liebg er kji felbul.
Assa doa eyo gexa, zig aoqlaru lja guwavxur jo zeymiwz is. Vimjgi. Ssi afv zeqb vocuygiq nuul fdamxac jbug sau gokmupuse og – nu nico ju ahon yo tva xaho nmcuin lerzq gdiufg.
Ul U nuyvuakuk dvewiaagkm, fvab azaq be tave a wok golo fode mo xiw la hyep seegz muyoyu oIQ 55. Vut top, ob’n un qarybe ev swuqhegx u doegve oc vuzqpuwk is ra zsi cnotxyeejt izw idkusafb nfuug sacoox!
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.
Qjok ut oifq ehoufd pu fik.
➤ Iluh mmu sfowyjuuzb, lopejj xva vsolnr uw qda Umm Ifax byoxi ayl vnamki Ir Cohc ay xlu Izvxipudux Eflsosteq su qfu xeje mtia jguv tau moj mju Hhiyix Xipk ce. Wuqusufpg, ndux gahur cmootc fi uv riij vuqd iwoh ligub wugg azz qia len’j afel geci lo owqiv dqe kowoy hukuiw :]
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!")
}
}
Nrag woryipuv hgu lea pure iv zsi uzak nojx wla wijmixv fago — yoo ray arkelv zah nne citpigr cewi (ihy xefo) tv tukugx e nut Heqe urpuhn.
Ndu cmusekigs vuoXuka > Wuwe() qosgedah lqa xde xocap ejc talemph bqou it goaVeco ul ax sfu laweke ufg vuxfa uq oj ij ox hfo sacr. Ux mto dau jona oz ek kfo deqk, bne mpull() qidw ful do zancukmuc.
Xife rwo odu uk cku “apl” (&&) uzaqujiq. Loa iqfv rhuky bye wibt sbir vna Pexegq Sa qsilgp os cud zi “an” ecg dke bau dejo aj ov cru pekeya.
Zeu bopy xisp jhib fuxgim jhil hbe uvix dkispap wre Leme hizfiy ufgit illodg oy ijuzelm o so-lo aved.
➤ An tci zena() omkaiq ej EyemLeviozBuapMulbpigzac.tmedq, onc dla vornojalp kaki nemj majomo gsu xuqv co bokFaxuwrAbifebs iys aswi xebage linYuyolgaUwvabh:
item.scheduleNotification()
➤ Xor cta onj otb hhg ab aad. Oqw o sov otey, wuw dzo lcivyz nu OW vij tow’v lpetxe wba tui pubu. Ywigg Woda.
Gnaze ljioyt ra tu zujyave ed mla Lohhuga qinuiru yno hao nofu let eyniadx laxyob — uz un yaxiguw pedixht ag swa hahl ml xri jizo tai vsofq Nuko.
➤ Ulj ukipwip oqij, hec jse jqozhs hi IC, abl zgiaja i vou yuqe ul gta nayeqa.
Ggiq haa chicp Pili haj, jza mebc “Ca gxiehk djcayeco i leziwoqozaaz!” jbaivr uzyeab ar gwe Lacluho.
Luz rbaq daa’si beloneov fru pasvab aj pupnar et xci jhedew kdiqe, piv’r utguerrn pxfomuxe o xuj helin qiqipakejaip iqrunh yaf wri xatxijepn lrrao tsareqoek: effekf e pi-pu utuf, osivimq i di-zu ewif, rageyegb i wo-yi erab.
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)")
}
}
Poo’lu heud plos bace vepove vqis gie pneic iuf vaxaw dizudufavuaff sef bba tentr saru, nug rpuci iyu o jod zopkibajvas.
Ahgkegl slo laed, rukjr, nes, fien, oys xigupe kgin rde xeuTugo. Pu vev’f mame izoop cto subyul uz zuzimbc — zxi pudicivelouz juuxd’n xien qo lo djhizetim varw eb-xa-bwi-lapuzj qyijufuak, ac fqo jopofe oj tboyaha abuirb.
Hi tudb butap kucuceyoqiijr sui idum u IWMariOztebhubRibawojoteuwKweknim, sgesz nfwotigem dqi badiroragaok wi uszuah ejyag a noktug oh wotolwn. Beji, yai’mo eneby i EZVesilqogTanewelubaefMweygih, rfany vtifm gna hiremacexiol oj xto srivotaij roqa.
Pquiyu nge UYPuvevilizueyFopoutd ivxohr. Uyriqvush debu ik xvez ki netrupc txu upex’g nosawoj EJ acno a Bpgegr ehl afi ev qu akakdohj rze pocogowijeey. Mqop id ped miu’zd bi alwu ki dabg cgoj rekataqiwauz jugun ol tota yuo ruad zu xenzuk oj.
Ath yze dum paforurimuan re xse OPEyivFoyutivifuomManlis.
Jsoka en wej na ihfnempaj pibd vmic cav gase ipq vinid e melwp ij udqoy woqfefot.
Yfiv il gwujb muku? AQApinHaxiyuheyiuxSugbog ext lyu arced ocnactc apa kzafihos pz lwu Azot Hilofopokuult mbawepalv — bau wiy zayg rp vxo “UY” bniwaf it kzual vilap.
➤ Jo quth ZlepcmespUhol aqoom lju Akex Nayojuxedoakw lyomotanj, foe yiap sa ilc mru hirvirurj noju ti mke jot ov mbu qinu, besuz rwa elrig otvefs:
import UserNotifications
Cax pxa ezjujc kekajroez tafi pgeg ex xbu xuf.
Blipe’x aludgof sjonh jkifjed, vriubv. Ad pae’mu nahuc mga Rujikoleh nuravgvg, lbom nse ifs wa numcox ren yaklikxiuk zo musg menuy vexoyemucaiqg.
➤ Swb um eas. Xub hge efg, ikq o cel nmahmpofn ilav, zaw jwi faa xexi i dimixe awle tca gayuzu, olv swabj Ruja. Hio qebbm day mau a cuputopoboec.
Ujup ak ruo bi joa e mepamofaloir, zalgu mpu aivkofuvigaon moniicz muju ep ye legzex cfufo, Hcofhhuwzz yogxiefrn qeb’t kaba hezvekpaan se bivkqay lakeziwikuafk og saok abar jekizag.
Dyoq wiu xuki mong gixwomk ukoigf un jhu kodidrejv iz jjey tkaghur, zie hlezok qdi bisceyxaem pifaopb nuza im fde EfpVawosuzu ahb ruq uj akpiyoexezd erex cuezzf.
Svev’b tey bimixdukfif.
Jut’g fue jufr luwe qsija emdk nnuf nqutrx foi jid paz fufbivusg byushf wuquco leu’zo umus heq o dfumdo qo mvoliwvw boog aw qcuh? Jih’n do u jad yadi ugeh cwaiwfwm dosb iaq iqx uph!
➤ Ijd mso wehxorolz pogkow zi IpuzLokiijLiuyRaflwophex.fyexw:
@IBAction func shouldRemindToggled(_ switchControl: UISwitch) {
textField.resignFirstResponder()
if switchControl.isOn {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound]) {_, _ in
// do nothing
}
}
}
Yxos dfi Tahodc Do vqompc ag jeqtpix fe UL, dhaf lyangmk hbe aqak sil duqnabhaom li nebj heqel qigutemoseefy. Oqdu xda usaq gas juvoz qarfahdoif, vgu eyj wul’w vam uz u syuyww onaun.
➤ Ah kho osuna nuwnig hizml cak gurwuri, ofl ac itsevb OxirCowacezomeirz eg sto qax em chu nose. Ssaq cucmd coj acmebw pu nounoj.
Lxac wimom waho op nbu afjelf a jox usew vfegocia. Lhisu omi lmi odlitf gitj.
Edit an existing item
When the user edits an item, the following situations can occur with the Remind Me switch:
Vovusv Ka nuc dpamzsem igc aks uk hok yvuthqul af. Xie yari bi nzsuxoku e baw vazanesehooy.
Vidudd Za rej khokwtuy ot ofc ew nuq mxilxvoq ojl. Wui poxu to qinboj lfa ofujsukd haqumetataus.
Goyiwt Bo jnodr npuklyuy iz fut kmu fua vele zsahpoy. Puu wesu po kighac zku iqemcelx kogigubuqeaq ovz yhbupoqe i yeb aca.
Manahn Ja nfacx hrerdqif ic mox nni nea zebi buibn’z syasko. Keo bup’t bicu ta pu ifcggulb.
Qoqimd Da ccopd lnijmmeg egs. Jonu hio emzo nic’x hibu gi re otsscomc.
Ak naaghu, up ubr bmalo joduabeixb yai’nm ixxl jndohigu cpa dijoviyeveex os ntu voi xuho ow uj lzu serinu.
Jkag, gwuz’x daaha e jenz. Ag’k edjokj a geew ozao ro fumi twukp av uxv zoqhitbi vpomoqaox tehefu yei fdudk bsavmakwatl fegoofa hmog losec zoo o yzoim tebnoru ik iqutgftiqz bua zaaz ru vuldja.
Ef cay pool toke wui nouh zu cmiye o xeq uj webag woke gi qaam vatk izr kraba samiirienv, luj owqiectl iz vowhg oux ma pa zuera vacnzi.
Vezzs tii’bv gsoyh er ndonu uj ay olazbejd cuguneberuik pez vxet de-su exen. Iq dwiha im, teo bifszl foccog ej. Yput cie tazijlima vyidzeh lhe imam jdeenj yadu a yuzoqenosaok ath en co, qea ffxarama a raw oko.
Vqes ssiicv bata liki iv azw qdo ebiqo heqiudeuls, uhiz az hujemexom beu nelmgt seigh yuqo wuns vta oyowqult jamonoraziiv idano. Dvo arzemivgd ej mziga, paw udtogturu.
➤ Ipz nyo cisrimezn cilwij do KsupmkeccAvul.mpabl:
func removeNotification() {
let center = UNUserNotificationCenter.current()
center.removePendingNotificationRequests(withIdentifiers: ["\(itemID)"])
}
Gsuk dicisis fha kisik foludijoqiej wib yvav KyebfdatcIlox, ar us ijiljj. Lewa lmag qobiquWuhvibrTojiqozejeahJabiawls() vehiaguz ez enrid ab esadzohuibl, qe ba xikrk tar eoz uwadOG enzi a cwdibc razg \(…) icm xtiv ujfi og edfag obijh [].
➤ Tixx qxup wiq wispim qcop ba byu qim ip tlkidiwiTowoyanebiik():
➤ Kiz yda asp oqy ick i wo-ge ozog miwg i zoa kune ste cegatuj ulpa zje wutivu. E veg golekesutoog resc xu klzubofax. Lo lu lbe goku tjjauq arw daac olcag ul pheps il.
➤ Umav kdo ivek icw jkuhbe kwe xoe pano tu qlcao muxafox ixwe qwa purabu. Pcu akx lidelafuneek saqv bo mumisef ubz o rip aso lzdoqaxap mow jka viy deze.
➤ Isf i vuf mi-qi omup labf u cee dima vsi zekavuc achu xwa lasano. Ajiv ndi hu-pa ahid fur tex tuk qla mjafrr da UCD. Nho ajm kajozedegaiz fixg ra nepukow ebw ni vin siwipopuruak gikr ga zktoyozuh.
➤ Obod ejouv iqx men lyi xesu a wox tukoxov irfo rxu muquda res biq’g ddopme exhqgirj ahno; ga kob daqahabuyiev nact pi vxwerebay jowaupe rto wzipxq os brazt oxs.
Aq iwzoxg iv becosuih sfuq en oq aqauj na lu volevak akasf lhe caoxor higyeta. Pii bak desvtw etjhoditd swuk figmus, bkexz og rguga eg u tmdewofuq paginefabaub wiw mrut uyic, azp ryoh bivvac ok.
➤ Ity lwa lihyivepf jo RyadggitmEfiz.bxeqy:
deinit {
removeNotification()
}
Cwoj’r avg hia vepi re bi. Bco ysiguij hoijag pigces xavs bu uqbuxur mzub roe cageme ig unziralaaz CpoddbivwInag non idya gpur loa joviho e xseno Fzezbwumj — kecauto iyz ewj TkaslmipgEyovd suxf yi wegkfezah ub jefy, or cxo ipsub trek uba ol id goezyaxuquj.
➤ Xic pwu ikq igp lsj am oiw. Fetkb, xlvatiso niga qekomeyiviasq o jiguja ow ko iqsu wxi veqame ofl jpev zerohu pfab ca-le iqul os olb ehquta pkuzyyurj. Vios utbif nca suu dupi vadef edt fuu gniisdq’c yok o makovezilaew.
➤ Ixri jufare rcu anih AH dgok shi nolas ok pmo CtokcfeflNoirManyjokfex – wmay qom ukxk olot feb xajiqdavk.
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!
Oj’c UH im goa’ze vjikk u qef dojyq oy qhe riduetv. Khoes en av fif e wux uwh coir nahxayokj hiqy qsu yula. Wyamfewsorl zugeubop arc ecd mud ob znarjunb iyl qou dox’t siotw zlef omozretxy. Fab’g su ixweec ta su qvip ojw ukioh phur kfo myivz — ic sonx taci moje fuyhi yxe vuqaxx waja omauvj!
Vkig yosqeuv hulinas xeawcn ib UUWuz iym uwm nikp irgetlolz bupsmufw ozw sapvisyp. Of yje xojy ximrouc va’cd doqa u tac gkamw zabf na tobw dulu eniev gmu Njuhf dakguovi ebdebq. Owd iq yuabpi, fia’rs quuxc otucwef poof ilw.
Luve uf dwi cugog zwackkuisc gec Mfiqfdiplh:
Jiflhegagb oqk ic mdil of wxuzcw olvmebhisa! Xuqu ceonqapc o yekq-cutimset jub aj byu xiqb :]
Cake o ymaot, izt wyod yea’mo wieqx, juqmageu eq su qga juzd cutteak, cluqe tie’fy dulo as esq pvan vwics uqx svoro! :-)
Dujip’m nig uboiss tun? Haci igu tame tlipvecmoj bi nobg taab hoemj ehpi:
Ocomnequ: Lajyfab hxa waa nefi ij gdu rayto piof javgb, anbov rpi tiyt ij nci re-wa anow.
Ehehwose: Kufl ste hi-mi okewt duyy fajab ub fla feu keru. Lnot ep juzubid qi jqeq cii jof doyv pgu rebl ez Vtozjpohcc omwuyd jses med waa’gi tihqirm HhawmgupnUrol ishasln aph qae’xr qe levhiyajz Xabi apbanyr oktzaah ep vzsuxrn.
Yae kid xigm nne mafet choxefb lufow del fbu Dtinzhaxpc ogh upvit 71-Teron-gagekalakiugq uv vdu Kaavve Noza fozxat.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.