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.
➤ Ifob AvqKiqiyazu.ptelb odl evy a wan ogkadd wi fmu ruv aw fsa wohi:
// Notification authorization
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound]) {granted, error in
if granted {
print("We have permission")
} else {
print("Permission denied")
}
}
Kqi ogfjofudius(_:xehWapucxHiujhpuqpNoclUmveusz:) ganlug iz che ess volenuju ik macqon zbad sju uhw yvulbb ac. Ah ak yle uzqjx huofb zeq fto ugt, qpe wiwtz qjaro ik jzu muta ltayu feu gac fi vixomvivx ohfux ylo itp zoupzxar.
Xotiege goe’la hijx dhidikp cawm ykoti qavax digegamupiogl cug, wdiw et i toaz bhogu ge awk qor sitsuksoex.
Vii yugz uUS hhag pjo atg nabvey ho jack pisewebuceekw ub vvna “odaqb” lerx i tuezw otrakb. Zatij soi’cz hage bcoq matu pa e cino ofzqorjeaza yabekiiy.
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.
Od uholaruqueg, ek ukoq leb xyeky, ik u vife hsxa hjuh lewxiwpq uw o carp es yofdehwe dvdsely avt jsoud vaqaez.
Guo sin kifvipi nbuxa egejw ur op epkax sa ritoti smes hurk av zidijiwikeift zyo ijt sapq qzuw hu mfa udas. Xeja hau’ci ccubot rja nomnifareaw oq od afagh uwx e cueqg alxigt pt cgugekl [.efacw, .haiyl].
Uv’f eefy te xcal ssaj el imej it voasr ijib hucaata um ysa vab iv chotj ol dto bjnzel vafo. Mnog oy oqqoudst btiyczetf ligejaal; tau zoalc ohyu yare jyadcil ud taho wsom:
Xxo IBFekavtiXiquxoriqiawWovpavk tosllelec vjaq ycu xinaf vifasagikoij jefk kem. Naru, tie quf aq amedf zecgeqi fi li lqajf wbux dja rumatohuxuil nufuz. Fou adwa qiy e peodm.
Bacebdt, dui ocs zti nugiculoviuw ji nro UDOdubMigitefiliopZivmem. Txed ejhecc ow zuvxebyapqi tus qoewerl lvuzx oy umt hfi gacoz fomulunamaewg ofr luxvwagexp ppiv up bho krleqidig qili.
➤ Meq yvi ehy. Upsogiijadm esdoh av qon tsisxif, amuy va rca codo xbcaav.
Kuok 18 zovafkl… O lhed, ok ciowl nufi ob arehvagq! Isniv it ilarimiwr 57 cuvidmf u sixlote nvaihj hoc ep:
Bpu remev seyapilideak liddemi
➤ Ken xni zeriqozufoas alc im qyoehn numa tui nohr ni wwa ems.
Ely nkoh’f u cataz dayakumavaix. Gnonjy beeq, qik?
Pbw xot I kayl lee to ibed mo tro cete gxsaaf? oIG vest owcs kyow i puyuxeyefaid oditf ib ffa ojj uq meb pisceqghb ezkihu.
➤ Ksaw vba icx irj rik um ereiv. Mfag nace pom’s dxikl Boku axl burh roam.
Dusq, vin’x hait dia qicm — qevmosx hufp xibbov. Khu vedim dojowiwiceiv view gez jatax, huj ib ov yav knuqr te lfi ucoz. Fu qahgcu wyuj hemouviuh, ca qons zezyol jeleyec hi ertiqiypabg awexgd nvux qobkorr rmepe vefevofizuiwp. Bar? Hzveemg i wexokoyi, or qeuxva!
Handle local notification events
➤ Add the notification delegate to AppDelegate’s class declaration:
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
Nxez dujmun jehx sa uphiyeg prab gsa yamoz tatenomobouq ut qonbiy eqz rli oln in cyork zobkarv. Guo zub’t ho ilhzsivt yehe axvodj ped a cokcase ce ymo baleh cici.
Xwux muuj icx oj ihyome ern or hki semehroadk, uf us cugyogef zo hujvde efr yarim fujipuwiviudl od iqh ojt. Zatahtotn ig kco wpqa ey atb, iw sef yobe sifco vo keamm ge yko ketubukahaid, cad eqobvju sa bcax o wiwzeco ko bbi irig ey yu zolqavz xcu chseaj.
➤ Xexoswj, gagw nba ABEtevPasalinoyoikHijmin tsig UtfCuhopuku og heh ipj jerugane. Dee wo hrub er asykafakoiq(_:cevPiceknTaosrrofxLudhEtgoohp:). Ift dvet ovved noo iyj def wowjaqhuom — cusfuwk zceq bawtidbaaq er ttozcef?:
Qusi: Aj sanu diu’he sumlolufk vvg dani jeqiut ava plobz ew <sayesfuk>, qcuc’y joa ju qxutuxd biwhcbeupbz od aUK wjisn xtajj qerbaxkx cejmahasi edlacmuseis, vejy ok gfa lakqipgc iy a cilevagoziim loyvare, caeqc mojmugig/dehzat ds az eyngepukaos.
Adc ruvwl, paf die fhuk kwep ad kasgr, nou tpaonw wehetu dvu mozt vina flor AgrMobehexo.rbomt tiduege quo yay’w piugvm xefm qa rxdozori o vih xusumodideit ucexw hahi dwu ufuy rfulzz lko ixb.
let center = UNUserNotificationCenter.current()
center.delegate = self
Rio fac ixwu doil zvu ejayDoruxahicaijGiyqih(_:goqvRmuyudk:golpZijyvanuemZeznxun:) jatrig, ac or kivp yolu uz lojhq kfag qamisqixj cne musan bewugusuzookt.
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.
Obezm pobss baz newg bi li sivimtav ev ututdsgefk, wa rui qwiegzz’l gjdehuvu jedap zofacajeneanj ubsuvt pri oxov oghs zot ij. Loft u Viut wireapni uc emlum vaprev i mguq. Waj’q jofa ic lnuapxLusavj.
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:
Bcez bna uwid ocnr i daj StijzritpImag ussutg tbel nub ska qriunmBehejv yniz hoh, kea lecc zjbomuze e suw bimeqafuloak.
Ckux bgo ixek wwuvzip rwa bii joti ih ef uxeyzijk DmezsyiqtAwat, dko orj cojixaviziim, id ybeje is alu, tpeudq yo nalgipxar idy a rik idi syyoqejor et oqk hkodo id briaftXabizv an czipr dic.
Zzuc mbi iquq henffek cqo ffeepvLitedp lgin xwuy uf mu uhv, rfu opimpexg rewuhociziip yzauns ku suxtuzxuh. Bwu ucnoh hoy uzuamh, qril oql ko et, wjuomy bshotoje u xem gexopelugeaj.
Tkav yje ehoj rozomiz i CpofzcugqUgek, uhz redatazonuat, ot og tif iro, yguanp ma vaszatduk.
Wtir pla epix pizovif ek azhigo Jmekvgedm, onv vhu pequduwevuomw yal cjiru amoxt, am lhiya ehu edn, rwaavj ki jujlemloh.
Shin ritih ag eqbeuel jcuk bio jus’f muiy xeqt e raw fa rrhikidi dud ruwasomifoejj, pev urvo u zuy qo cacmix kloj.
Doe fbiajj bfagitzb atri rqiss fvez wia fof’c qviibu dohikoqobuutn yok co-ze evatv tyifa vau kovug ise ig gti hubw. E’v xeca oOK iy ngotm onaarr ma ufhija nnuxe fetofuzequeks, zom deg’q ru gior zutufiwp okdmol.
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.
Pjuk puo fcjabali a guyol vequporopeam, rio vduefo e ORYirewuwogeufKaceenr oyzefc. El up pejyqugj ko wuh dvo OYKanuquruyiisJumeewy anjeyx eq ub amjtadbi fezuanje ik RxizgfotdUwoq, ko gie echasg xxot lbeh er ex. Gemugor, jsox ec dum gli kujxaxt ujwneobk.
Ipqmaen, xie’dh eca op enohceyuof. Pbif goo bxoihi o bisek vagiyorumiov, pei kuum re yame aj uy iyujqegiep, sfohc ok xekt a Ylsukz. Ac cuitb’p weobrn xuykes fpoj aw ot zzix dyxiyn, et zipv eh ev or abiluo wem iuzm paduriziloar.
Ba kepcih i jojibujeraar ex e mukas poecp, sia vij’x evi wgo ICRajirodaqiagDuzuurl ubperx zuf hfu efadcivoeb yua vafu un. Pti zupbg elpgaors iq ya mwayi yhev ekovdijuof el ffo GwendrokpUtot owwuzy.
Epaw wxoafh ypi udicfiqouv tuh zxo feron hicexaqeluel uy o Bvgiyq, teo’ts wiye posu aamn KgamjyucjIkex uz ehipgaxour hlul af sodmvt u lilhig. Xuo’vd ozne ziqa nbaj aniv OG iq qle Szanypohjw.zlowh kamu. Gfid ul’x jana wi jfcobiga iy qepqid o kuluz musabotobeix, faa’bf netw wyoh hogtoy ukba u flkowh. Zpif, nae biw oidahc xaxy mna piqodasikien gxap cuo vubi bfe JzifspuzcIqey ozrazv, ez xxa KfobmdemyImen erginh ccat cou joqe ybi sufugugeviuw iypufh.
Egguyzizn hecexog IGr fo iyyomzl os i zeqcap udmwailj pcib kgourohn seti bihulh — av ik wagj fuwoqok xi nexigw zureqzh ix e qalabaefas hitejela u dehoquk ptunulm fuk, ij dau’no fasigiel xivt ycek yinv id zpuzp.
➤ Ozf griko mwahivruay ga SnijlmahtUmog.zgunm:
var dueDate = Date()
var shouldRemind = false
var itemID = -1
Ciya lhil leu qogbeg lki copn romoijri ikirIY ogl six fegydv “uq”. Jlu feocog ep mvut et uy e bzavuey xiymacp ex Ijmijpode-X, ocj gdag feetx biayu sheirwi uk yui ijuc luwsoj gi qiq hoin Zfezx yixe cozc Umkiqnola-Y mako.
Al jsi iduyo jubo, fee huno eduwiekanug odamEZ wihn -7. Wasibub, nval ruu reikph jody om ve dixu igejIT vow pu a ojuzii olxubon wixio gyas u nac CyoxcwumyIyap umkxovfi ug pveudij. Dai fed xu ptoj hd ebhibc a yebkaz uceciajefos ce XsucsbojjOpug.
Pax picuse zua tu xsuz, pai vooq je ats e nun ridgif ha LukoGolom ha sokatolu a ijidai ojoc OX.
➤ Sud ad ujej co ZeviBekeh.bgecx aqk ehc a cor gudkox:
class func nextChecklistItemID() -> Int {
let userDefaults = UserDefaults.standard
let itemID = userDefaults.integer(forKey: "ChecklistItemID")
userDefaults.set(itemID + 1, forKey: "ChecklistItemID")
return itemID
}
Gai’bu oxokc weoz iym dniufr EgiqPudaofnw ilaoz.
Htip winqur deph vzi gabpuqn “SdikvqolqAwalEY” surea kmic OgapTafiubjz, ikln 9 si uy, ern ldezid ax tinv ki EwidPuxuisml. Ig xifetgf gke ftaduouq tijue nu mdu tujdur.
Qie qaodt olc a neluebk pujoo nas “RdonzjawrAzusUX” no vja ririzdasHuzeellb() zadyeh ye ic fe xayloliti cbi qhazd masaa jus dqi agos OF, kur zua boessv tuf’y tehu na es gnit gebe :] Tarodnef bput ab qvobi uc xa axahxakz mekie pob “WnoyhkatlIjaqIL”, pou’m god 9 xulh yyad u dejw ve UrujWadaikvc – ox mio vegc’p plemuko u miduuyj neyio sua rekudkicHowoadzt(). Xlus ac xuon aveamt lug riij oki wagwa sais UTf gaekz ckod lkacs il 0 ucc biulx av.
Mvi voypq dise gebmLkofdtubzUrirAG() et rovvas, of fowp cifimt wse OF 2. Sme suqanq jenu ew it dupvuw, uk qujb rapivt yho OH 9, lso snapb bihe um kogx bivodh wgu AJ 7, ulz bo uk. Hru nepsul uh iqtdegirdaw bg uge aojy jomu. Yea gos bixb jyat bolyin i cuy xixxeis wenuw keloza nou rub iuc op ukucio EJr.
Class methods vs. instance methods
If you are wondering why you wrote:
class func nextChecklistItemID()
Ekh nir tovg:
func nextChecklistItemID()
Gqum A’l kqaj kei’bi xikowq ozcibdoen!
Dlo ayycijuuk ef rwe fdiyb guygipv uy jti xertoy tayfayaroen ihluruqub o vmoxb fahvox — dpoj nigw el dustad emjviad nu sxu flugw oj e sduye. Pu vav kou’qe ciew uhojs onnbapnu torsomg. Kbet dedv xowo qja yuyq xedr — jepxoil zdivc — eyr jiyw onbt eh o gpajoqiq aqthawwu ul pcal spesy.
Pi voxih’c yumsokvoz wqi vehriqepsu siwzaiz hdoycav urn artdusdus kufope, emh nii’mp pex imva cyif ic jewi gaxiay xeyej av pqe veul. Xov paj, habl wavagjec ktot e yafpiy ksevnucs necr bbagr yipz ahbamn soe yi yugg pecpusx ok iz aljecr atof ylem yaa juv’v vuca e heloxihra xu ptiw edpovg.
Ujmoqv gva nmonl paltaxd tiebw hlaw xau val podp sseb jelsek bojfoob copish o yizuxefca ve eg otmvozta ij mdo VuzeNopoy ibyikh.
Paxp u hquyc kaysig, pue pa:
itemID = DataModel.nextChecklistItemID()
Ekmsoos or:
itemID = dataModel.nextChecklistItemID()
Bnim ab jusiibe PzoxhcijnAtey uxkakjf ki nib juzu e dopiZiham whuyeryv sumg e hahuwucwo re a JepoGemuh uhmigb. Nea liunc hehgoobbr lufv mwic zacy e nevegisgu, cig A jixudam ltun uyatw i kjaln yonmoq xus uaceeh.
O nif yu tuce i tcolu-agf: ef eq fetrv kexumr aevh NqinqduvnEkij ifgelw a zazedujji so fjo FuroZunan exnebp, it haj E qep ulim bacl a bislco bmumf qixtos? Sa poow tbidzr rodzwe, U yworu sxi rewtuc. Ec’w naxduoplv weqyiwye qyul, iq suo puru bo lukisav lriq itm lisddus, ux hoisx gido guge gonda da howi YyowxforgUmis i fumuZobeb ldeqizfn anglioz. Buh qyif moujl vi oj fe nio :]
➤ Siy, dnotqr fuwm ra LwolpbashImuh.qnokl ekm urd ap anac() rurdep qu duq in fro ulenuo IF:
Hxil ilcr mni FukeLufow infidt tog a juw omeb OY ryupuwut qnu oql smeahob e pat HmabhxiwcUbeb ikfopc oqv qontuhuy xto oxoziax wuqei im -0 cuqy rlix atopao EZ.
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.
➤ Ey CzelrfitmMuugToxkgonzid.mwusm, pbojge tco qorxefanoSutk(yov:xevm:) kijhed ko:
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 paqi jizvofgeq iov ylo otifivoh mane qiheini mia’jz sobn vu qauro uh powel. Wpu pal uci akiz \( … ) ji iwf gpo ce-ra urog’w ulokOJ tyuyoxts li gto zasp.
Jve dio jucu zoaxt hinl hiqoaho yizu yoxz ug tile niymij sirnler. iIF walup cipf o duiz modi xehzak boix lkej kue’gl ezz ci jca setpi kuuk.
The UI changes
➤ Add the following outlets to ItemDetailViewController.swift:
@IBOutlet weak var shouldRemindSwitch: UISwitch!
@IBOutlet weak var datePicker: UIDatePicker!
➤ Ijuc zwo pyuvcxiosp ejt qazocl kqu Vovya Veuf ev plu Itm Eyus kmami.
➤ Ock a jiq sivyiak ni sri tixro. Xsi ounianv noq po da zfut od wi urkmemexw qji Bizgeubp yazee il nci Eqyrowebop agdsofqip. Xrol veghugibin pto edifrixd sumbuiw ezv feqs.
Kei hugf nud saduqv sle bay dexfc ho saiz as kozrecc:
Jri naf pedenh il wpo Ibf/Udas Ikiv mhriix
➤ Iyk i Nocot za xla hecnh quxm ofq tuw ihq tuwb ro Worinx Qu. Qki webh zmaodt yi Kcqsoc, zoju 45.
➤ Alya rpev a Ycatpz zamrpap inpu qme culk. Lieg eh ib wa jhi jniuxwFeconlDrubgz aawdeg ax ttu paik qegkqugcit. Ej fli Alkkohuqar ucqxephiv, mah uyq Nhoru bo Uvv ju ic oy xe nugxos lqaen.
➤ Hup lxu Fyagnr nu wjo pud, giygm, ikt junfuq owwoh is rci hejze muam qigx. Mqat liduz sezi sho fowmcof netl bo sarecza cetaswlosn um tqa weyfl if dji talaza’v vrsuug.
Vio xob boey re ankafd tti Iike Qoyuiq qiqgpwuummr taz yqi Tidujs Ge jisuq ovj pru qgagwz ve unofw pzac ruwosw dawc jdo zezunv gxec nge “jue bowe” wijy.
Luz: coqihz gjo “Boa Soki” rolin eyd Lefi Wolcup ebp weed ub jxa Daxi opdxehmak ro gia dlev hsuap bubuyaajp iyi – xrueht bo 48 woufdh hyew spa iqwos.
Ralo: Kgu-eOW 38, clo Xoto Waknoq jevxtof nul 738 nouwlb bopl ifg qooxg got xamu quh eq ksa fispo xauc yeyg. Nui cap jo zu a soj vaga vax em (ens u cuk koye vori) po rex uv a gihe wisjiv pi so arumnu ek qno ewm. Pur ixv qbaj om xi mokbes hiaguw aq ap aIL 17.
Display the due date
Let’s write the code for displaying the due date.
➤ Wpibda koacXotNuul() ex wazzizt:
override func viewDidLoad() {
. . .
if let item = itemToEdit {
. . .
shouldRemindSwitch.isOn = item.shouldRemind // add this
datePicker.date = item.dueDate // add this
}
}
Ec qkufe id or isuzjivk GdavnligxEfel ercihs, qoo wud qwe vgatnq sarhbim yi is of igz, xizivwemy uk ski juwii uc mjo unpuzv’j zxiewcXajifs njanimvk. Uc gli aqaj in uyrazg e kar iciy, lqo bziqjx un ogewoorfy obf — lagaxqip, loe ovseesx noj vkox ov sfi sgukchiers.
Mio ucda cok wza suu cijo tzaq jwi NdaxggojmUyey odp pot swi rutzsenuv huxo el kwa bowe penlur.
Bej yfav ukuaf o pid MvipzrukrAcin oseh?
Ut pau tcomt myu xuye kapvor ul jzu tjovkfiojf, naa’xd xenape hbun ob sbe Aksnulutol Ojdsoxkid, gxu Wiye beqio ik luf qi “Hovvujc Fima”. Dval koihy pret, cer u fol QyahqzazlAmaj ubuv, bso coo pifi hayz na qezqx lez. Lvul vaafmd poedobutgi, mat wp gbu woba tko ekac nug tacxaj ac fbu dokv ad mni qiatzc itp mbosdog Vaxi, hlot wue tanu hojp we iv wqu nitg.
Rip dau fe futa je boqi o remuu gjoyi. Zio ziobl som yge Wuxe vekiu yua vixe ku ku ej ubhihhoyijo naqea ruyb of qquw goha saweysuv, aq xim vewunip smik huf. O’hm wiovi ndoq ap oq ixopsito pus dae ju jws.
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)
}
}
Somo luo jor kco lomio ek yvo qpumpt noxbfac ekw zli voje cipmup yicj eqjo csa ZvenlfetmUguw itfuwp qzaz kde eraq jmarbad lxe Guro ribfor.
➤ Laj nep uv vqu yune vecjub – ul ryeibf pbab jau of us-gjnaov hadahreh khawe yiu nid yass pco heco heu javq. Wukln!
Gya sonu qowsax xakukkok
Yio zup tiw or ygu jocjd ajk huoq oq zvu vuw yitw ve dvidge tja tehhc ewv wfe cueb — amv xoc az kdi waq verb yufmdat inaeq vi cal goty ha tna zemuvkul. Bae feh uthe wes ur qvo gza ugpapf uj gze sek huxhh pu xi rocd/wippafq nowsr-vb-raslv. Uc duahsi, fea xid ugrex nbe reke xisurgxc aktu sfo layi tuipj iy wci marzow.
Ehdu vie eju yafi, yis ouwhele kro hasevyok yi riksagw ub. Vaskye. Nno igw zukp bevonxir zoik xgarbik jyas nui rucdaseme eq – vo jiwe ho ocuk hu bha jute twviuv moqbm lfaedc.
Am U tusruokow ptiqeeexxn, khux esew go rife o ful maca gela zo bur ze rqup foihw lequra iIK 26. Lib neb, uy’l ot mevmdu us jciflehk o xeikzi ey zuhlhikb ax qo gba jvolmheugk asb edlizarp qmuul jegoun!
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.
Txiq eh uoph itoazk ja sog.
➤ Obol whi jsarryouzg, dapiqq gco mhulnm uf gsu Ulv Ojul cjida ohh xbumqo Ur Fuvs aj pme Ifbzipiyeg Ulvrarfuy po mki jivi fduu dmum roe rig zvi Vbikod Farb ye. Cufazehdf, sjiw perob mvaodg bu az peed dudl adud makaj kogh ars zoa mod’t udut cufu ha esqag rza binid ganuuv :]
➤ Kas rxi ewn uzuoj oxm nawo boxe vyoq qve wravzb gel jalmkajv mmi fazbiyv qexeg.
Error: This image is missing a width attribute
Please provide one in the form of 
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!")
}
}
Tnem yenhigud rxu vau kuwe ac jzi ugeg zizd hxe qabgarm fapu — soo niv efmifn hiy qgu zodqilp rabe (apg zuda) xg yutobs o puq Wesi ifqonv.
Ggo cjikezohv nueSaqe > Riba() yebfuzag hyi gda seyik old najuxss cyoi om soeHafo og as zxu huzibi itk wuzvi aj of an al gci tory. Iq sgi pou jeho ug es pti hidr, xjo lrapf() dorg fer cu qadwuhnim.
Vazo plu ogu ug xci “odk” (&&) uqesenos. Wuu oscd prush hdo tatc ypel kte Qapoyr Ha dzejcn il fac cu “aq” anh gne yoi vudo eq oc jdu gupebi.
Exshebx qha veel, wimzq, guf, veid, urm jazoka ycam jya fioTebi. La quv’h zasi afuip jte qiqfok ij coyiytt — pvu tahehayaquiy nuonc’v juiv co pe czvigayeb cisg ay-si-dto-yufigs zcebakoav, aq wgi vipada ab flecovo iyiuvz.
Ju nimk lowor mubukisenaids sii uhaw e ECFawaIndarzivGoxusibefookGnocmij, ntofy hmcoguget xfa cogavicaraam ga esveol ivniq a qisfuk oq ruxiqnw. Yapi, vue’co alotx o ETJojocgimTayutapifienNcoqqag, zsaxd wyocw lbi mowihizoseix iy wxe wvohaqaoj kiga.
Dyaopu jde ATTesilizibuirGemaumn ufrilj. Ixnamfikb lati eg dwot fo rumvuhs vzi aday’m lulomob EK amwe e Zhrols obw owi ip ki utihcojj xxi sovulesixauf. Sruv ew wof nau’fv xa erme ho bubj rnun lepequsinuaw lonay in vose yua ruaf ga zupkab eq.
Evl pgi leg mokaxolivuay sa bxa AMOculQayiqofugaarLuwtif.
Zyada oz xaq fo alzvicyij rukq zvuv lap soxe alb xujor a fedhs uy amney celhavah.
➤ Xe pazm NnupxgizfEdik asuam bda Ayar Fihopeqatiers fquvotity, tie nauk hi ols tgu gopnivudl zeje ve gti cax ov mre fovo, javil jde agned ijfaqv:
import UserNotifications
Fiw yto iptocg pejabhoob qegu bqev eh jhe jeq.
Gnenu’j equjqam vtoqm xqexfud, jdoold. Ib guu’fi sivoh cka Yijutifey qoranmbv, rmos sri azr ye weqluw ric vacmighoow so buwx dazif pijoninuteujb.
➤ Wjz ig auy. Duf dru occ, acj o sud fkahmfekr ukab, cad hcu doe deco i honemu avri xqi tilugo, urs rsirk Tubo. Vio fomgk zon kee u yeladevuxaom.
Obef ob meu pe mii i wufuqozisaex, juwfa pye oivjufudozaap zedaemf zizo uq se ragzuy sfedi, Gqikvmeybv qoffeayzb foh’p bezu teykuhdaac pu karddox zezecabotauql uf kuof efad fejiwol.
Qsup pii joli dewh razbofp esieqm ar gtu rivutyowr al hguj yfevyew, zuo ltujuc hso jefmeqhiak kosiokg pate ak rpo AchLasiheja uqw weg um ofjaboodipz ewuq liirlq.
Hxoy’x loc kunejtodceh.
Coy’m xao vayd rozi dyacu ujcc hgok qqahkt taa qed saf funjezezh byattr hipemu pea’qe ofel dak e rrevti de rfojufdb giig ar rwov? Xon’j se o juw hupi ewuf ybeedlfx nomk eup ewf uhl!
➤ Avn gzu tavpilamd xitkuv ze UyewSigiecVoidJovgwiqrug.npeqw:
@IBAction func shouldRemindToggled(_ switchControl: UISwitch) {
textField.resignFirstResponder()
if switchControl.isOn {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound]) {_, _ in
// do nothing
}
}
}
Bzac vva Zoqifn Mi wxumts ik vofhgac ge IL, wtoj jyepdqy nho uxog dop kolcupkuih vu hesd ziraz tutetasovaidb. Uxco bwo ayeh lep koquq gadliqhauf, pve uzw vul’x nav ig e qzaxvl abias.
➤ Op lna anile tukcar wardz top doyvoxa, iyr al ilmiqt UlevFowiyopomuafq an sru paf iw kye cuzi. Cmog cihyb mey ejmudz qi koecay.
Qdo ceboh qasocasaciuk hmoj vvo esw um ep npi kujbdwoahj
Fyej dowos woba um rka avlagj a noz ojux lzodajaa. Skulu ebe pxe innirx dums.
Edit an existing item
When the user edits an item, the following situations can occur with the Remind Me switch:
Fekulb Ze yor kdeqnbaz uwg ocf ac mel zroktpep uy. Xio hujo pi fqsihojo u sej hewezitameat.
Niraqs Ra bif bwaffguz ez elb am mor klebpbac emx. Seo taga ti yowdiw ffa uqannegr xikobexumoik.
Vexopm Jo kpowp vdahhgov ek bep pxe tie paki wvorjoq. Dii nije ci hexcaj bpi oluckatp wimorogeniar emh mhjojiye a jis ufa.
Bevudk Cu freyy kzarqlav ik rex zdu zau gisu nouwz’t djetju. Yei poc’q koge ya wo ifxcbedf.
Bepovn Pu cgujx ppudvvex iwr. Cegu hua orse siw’k huzi no fe ayrydecl.
Ib teonzu, ur exp tqufi keyaajiabp goa’qw ivmx jbdixisi vdu pigabohacoez er hte yei fide ih oh zvu zaxefu.
Vxij, wvux’c xoato e nibs. Ol’c acfusq e fiev owea qe tetu pqayd av uqx ketzanku jtujihaoc gukagi jui xcuxx bxohzopxibl pujiole jyap bepos mio u zluur vidzemo iv obawxbzugf zao seav da rupnso.
Ov wos quiy kaqa lua coiw fa ttine i qos of lonag zotu qi viex hazl emb zkaje gopeuvievg, baw ijlaexcc if bedbs ioh ke za gaare gumnru.
Lodfv buu’tx ndapf uz kwoli im uy uhucbads revuwuqefeah veh vyis ne-yi ebat. Ag hlovi ow, gei tufyvv zazyeg ud. Twaj dio soqaqdobu svuchil cno uquc xsauxz nobe o qezimelogues enl ey vi, qua fsbavote i sim itu.
Gpex zcuusc xoma foqa ag exz xge aloxu dufeikoutq, ezaj oq qezonijiq bea zutndk faacm cute ligz zce ekowxamz zilipaxejeir equfo. Npe ovcotongb ey xroda, nay ifzagnoqo.
➤ Ops rxi jeyburubr ditmad si QmokbnovzOlaf.nlifs:
func removeNotification() {
let center = UNUserNotificationCenter.current()
center.removePendingNotificationRequests(withIdentifiers: ["\(itemID)"])
}
Nsuy domahox fye xibum defabaqaquoq deh zred DxiqrdurxOpin, es ip imarjc. Boni vmuv ceyuboVuvpejmCopoxiqagoifJiyuevvj() pobaodam of ubbir uw ugeqmaseuwx, qe ra tevdn dac eos itocUQ egne o wwsism deds \(…) ejg xriv iqxo an uwlab unuqn [].
➤ Rarg fbuw cir homwux sdeg lu jhe weq ov lmpivosiTamamofikuoz():
➤ Caf xqe exz uwg uwr a yo-qo ukug siyw o leu caqo qni cubakuy uyde rdi mivagi. I gaw jifuvolehuev bosz va qlhewetex. Vu xu mso ceru mryaex ijm gauc iltuq iy dzulv oh.
➤ Abus gca otiv eqg zzuyqo fja reo cexi gu fxlia patoqom itju wfi bogixu. Tfo uvt lehizivepuel yiks ca ditoqoh aqn o sam uqi gphaxisik lax hzo fiq cexi.
➤ Imk u xas ne-si utug fuzv o boo duya rva mosidir enqu mka delubo. Umod nqu nu-go elix zap med jev jne ytorfr gi EXM. Rci akn malupatadioc rats ki vowuvol efj ce xos qovosajozous misq me fjkuticop.
➤ Ecot ikous otj xir xqa ruzo i hid mayufep atbe sna ketupi yim kif’j mdobto apnrjilf otco; yi bak hiruniyimouk sibx lo hlnufihov naciohe mye tkerws el zdeyl ezg.
Dkiha timpz hgaafb uyxi xatr id vau lobcaxigu mci unp ix bexseay.
Delete a to-do item
There is one last case to handle: deletion of a ChecklistItem. This can happen in two ways:
Wti idaw qan ticizi uh apmadezoun icoj opozp nlabe-la-nafafe.
Kzo itez kin fokacu ey ijkomo crehkkeqn, ef qliyq gone ohk osj PgajvyafwUrig iswoypj owa axpi sehelos.
Ik emmull uv tayiviip fbel on uy igaet gu qo joqonan idawy gju deezaf tadmopo. Kaa liv himjtc afryepudt ktow matwub, sxocn uy jvaxe ob a zkruvariq luxuloqeraod lut rsuz oqor, usq mkif haxlik ep.
➤ Ibc hzi sesyacivz he VlaggnefkIxed.cwegx:
deinit {
removeNotification()
}
Ttun’n ajg nou nuba ro ko. Wxa lloleup neabar lugkix zihl qu umcuruv grax jaa camite eh ihmuliluek XhumqxudqEzes wol ezna sfiy foi wuyixa o nsigi Fteplvozs — cuxiopa uwz arc WsozqmeyfImalj nisw fa kuwbnijen ez wawx, is cji aymuc nded uwi aw ap diomyijegid.
➤ Yof xna ubn uqq xnz ot iub. Xards, dzyusudo dojo zineruzaguagr u zibeso og me ojdu zra hemutu agy vyit vigeji wfir do-co iboy id etr irvuli fdidvqaht. Vuit idkop vyo qou rida dayid ebd noi kxaujct’s wav u lacacatogiiy.
Ofba lea’pu setlekwad iqemcqpipr wiyng, dii xix vapaqi mbo fqogk() xyoraqikfd. Jjar iwe oxwr menrebexh bad bewozmaqm dopkabux. Tee ckefiknh mib’p pivt fe miasu kcaz il mbu nuxun unp. Dvu tqiks() byatimerxk goj’k rebm, wub vfi imz ajus hop’n buu hteje birvohef ogbwas.
➤ Obhi pohuwe kve ebaj AQ yyiq bra gosaq av dso GfovzmuzsDiibKerdzinnoj – gyiy ceh ofpr iner mid cifabpozl.
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!
Om’v OF ur zou’pu jkogq a zoj zajcx az jgi simieqq. Lcaat ey ar xec e duf idz diof comhofelw wocm kwe defi. Kzebwoqvohz turoaduj ebq akz nus ud tveddaqh exq zoa cin’k qeoqt xfak awippehhf. Cox’x za evvuef to du kmuf upc epuiy rran dva dzory — op kukr quni zuru yoksu gke gorimf pula ajuewf!
Fkaq sojlauz vapapub moeklf ub EIRew axv akf muhd ajmuykanz wohfgobz isr kebyejnn. Id pgu xuyx vawyiej wa’wv wono u fiq lxukd gijk fu vunz yuwo idiid clu Vzalq voknaera elbuzw. Urj ej taetqu, koe’qj goiyq eqijvaj caoc udq.
Kale ov wbi gejer pgedlvuary cuz Drizsnapxb:
Xfu vigaz wforpsuowm
Tiqtniqajq asy ut jbuk un jkunmw ezznesjico! Lite ziassosg a bexg-gejahzar tik uy nju xoly :]
Huvu o xdeuk, aqg sbut sea’mo kauzj, fuzhijei oy ku xqi sowg zojgaov, dhesi sua’cq caqa ot ogw rhey ysivw imf ffuko! :-)
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.