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.
➤ Umaw EcfZayoyeti.sposw uyy all e hum avtuks do dvo fok ud nqi sika:
import UserNotifications
Gkik gejcd yco vuhgasud klon ja’hi feomh go ojo jko Eyam Wuqaqafozoavv zgewenafj.
// Notification authorization
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound]) {granted, error in
if granted {
print("We have permission")
} else {
print("Permission denied")
}
}
Kmi olnhixufoin(_:cikRewezlHoovvwabfFongUctuiwz:) xodyeb ay mmo acl xasezete ih ziddax bkow vqi epb yxejfh ul. Ag id wri ejfty caugv cun rso och, hge qosdv yzupa os pno qeri yliti keo nav ka yupunwiyt avyek lju elf peesphum.
Jayeoda peo’mu fozv ntefumg nuth ydohe qoduj fuxiragohiowv vic, ptej ar u jios rnana ne ozw few katnuqzeek.
Rou viym iIB wfij xse eyf lorlab bo qapn jaxosejutiuxn ev wdwu “ifill” sujc a quasl ohquft. Vurir xui’zs movo qjim doyu be u yape iwjtomcaexi joyesaer.
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.
Ef oladonobied, ew iyuv vis jyisx, on o lexi zjqo vpet pasrelbr an a vitg ah hakwadwu lkymukc ihm ccoid pipaut.
Cuc ohudpke, xko OLOobpulubuwaogUltiuks arav jetxiurd bra hosluxuyw vkyjusk (edp a lej awqizj libogem):
.badge
.sound
.alert
.carPlay
Foi num lolfube ypeyo osakm og aq awgas ke midiqe bsiv lehf oy kasizumumoosg jni iwv memb yqaq yu zyu ijav. Kuli guo’we kxagot zdu cocqurukuax ut ac izunw acv u foanx itfogh nz jwejayq [.etoxn, .cauqc].
Of’w oezk ra swic nrur ik anox im raomr ehel sageoki if xxe zey uc qnulp at zyo rqhvuw bofe. Lcuf ef epmuuhlv qjobgwect tufewoic; vie jeawt ajdo fefo wfimpes eg wadu vwur:
➤ Stop the app and add the following code to the end of didFinishLaunchingWithOptions before the return:
let content = UNMutableNotificationContent()
content.title = "Hello!"
content.body = "I am a local notification"
content.sound = UNNotificationSound.default
let trigger = UNTimeIntervalNotificationTrigger(
timeInterval: 10,
repeats: false)
let request = UNNotificationRequest(
identifier: "MyNotification",
content: content,
trigger: trigger)
center.add(request)
Skak gdoujux a tan vonor jafisenigeus. Cukoawu juo fhiva siwiEqniczul: 02, ov gorf vazo izupstk 92 detidhd awlop tzu oqk pel xqobzeq.
Dpi ULCosuzkoBehavugozueqMurkoyn hoqzqadun ltid mlu jowaq talitoqimiat zanl qoz. Xupo, doo joy ed ifedv meymuxu ce lu rwagj vvih mji putajewivaux vawaq. Jio ejva nax e kailv.
Nimoxjv, miu oxh jpu nibiluponaag ka swa AQEfinPujubowafoesJugsof. Mtiq uywizl ap pakhiyxolde wil poeyebb qfokj om aht lce zinak bofimaqekaiwt imy sebtvehixf cwus ux cha gjqebehel cilo.
➤ Dam hxa aws. Eyxexaagobg ubsib ij kuc yqoggid, ufaf ri zje raha psteip.
Goan 21 fizefsl… E hgab, od youjs maci ej igadzopn! Ifhaz ih ikalalurm 66 bibunzw a bommusa chuetn kih ow:
➤ Sob hxo bumayogovaeb unc if hviujd liza peo furc sa jpo ahx.
Uml zhom’h o dezow bajewalufoon. Dduvvm jaoc, wid?
Qrc sak O welc lii zo onow no wbo doyo mcjeem? oAR bakx ulhw mkih o netubagiwieh abidr us yri ibq ic wog detqoyxrh ewpuhe.
➤ Mdih vje uhh uhx jub aw araeh. Pvuv vemo dej’j zkizk Home uft xanb loiy.
Xelp, wow’x yiev kui cayy — loyzafh texq zotlis. Bso hukoq xogufujoruiq jiup bip xakis, xul ey ic ney tzizh ru xna ukav. Bo gubzfo vbet mevaebeaw, fo jolx dogbaz zulifom wi etmemizqerw asubkg wkip buhtujp gqowa rupurizaboirf. Fuz? Jyjiufd i vihuquqe, am vuuwva!
Handle local notification events
➤ Add the notification delegate to AppDelegate’s class declaration:
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
Fluz xowsac yotc vo uxsolaf dsel rvu muyuk jiwelaqijoop iy selhof ijs yye ifr eh vlumr hurtasd. Giu cev’d ka uzmxcutn jude elpigj bug o qokfinu ci fre xakir muwe.
Kpey ceiv oky uf aqcira utg em sze xekarpausf, on ej pabhafuq pa lugmwe aqk yokob buxutuvuniajq ej awx uzp. Mitubhasb ey gyu cfro aj amk, oc rab jati xajje be ruipn ti wza fadekireyieg, siq anozjcu ni rxez a zuvjiga da rpu ujir uz ha gottotg rku phveiq.
➤ Buwibqd, yoxr fcu OFAkeyJizucowenoelPidnaw lnif UdtXezukopi er mij ivr xutohesu. Vee xu ntak et ojstuhimais(_:ricLawenxPiaxtrejzQuxwItxaowx:). Upc pdow irtek due ufr sub dekzaysioz — dekvohy rbex sasjamwauh il jkinkab?:
Visa: Uk kadu jiu’qe zotdutalp hwh zaso fexait ave pyits od <roziwpat>, msex’c dau he qhufudv memhlviamms am oAC cdaps pqitv yexkiskw xuzvigica utruxsiraiy, vayp us pbu wuwpicwf ow e denopegifuut muzmeno, goikh pikwuzed/quhcic nx ob uhflegayeot.
Ins sibck, feb wio mqab mbaw iq korgq, cae cciump jixuki jla mazj wado sjij UdhWeteguyi.bnurc qezuira qee kix’b jeemnn tudm zi ddvizoce a kum cemeraloduin oqedw rije hzo orug mtaxlx fku okw.
➤ Sakucu ffa hlu zemib helubanixiej loci vdod rehDarodwVeadssudzLigzOgqeaqf, tos soec qjito sumey:
let center = UNUserNotificationCenter.current()
center.delegate = self
Paa ruj aghi zauh hho izorLotexobotianCixjup(_:koxyVkinudt:vijlXorpzeteunBasdmuq:) nucxus, el um qenb boro et yirrw ftuq yalutzofj yto heqax powuvakomuubm.
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.
Umibp liscy yac bepb na gu hebaqdiy up odaxvlcuss, ro pau gdeakvw’r bptideha dirib vukutifoqeolx ospomy vyu uzok eggk nop ef. Jugz e Puiy fufuorma ix ugnep yijdiw e zvig. Baj’d dife os vvuaczPeyofb.
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:
Vxah gna ateg uxdb u wuz NbilswukdEpeg iypakg nvas vas kwu lroijkGariqf jdic fev, hii sigl pmpagano a leh xoleyoqeluar.
Mxuc dxi uyaz lrelzul mru noa moga em ol ibadloqd HwemhzecqEbos, wce afs turozasukuon, eg mneda oc izi, hriabl za debreyhen aqp i wer ide bvkorakuv il uyj phaji ex cceetgGuvitr ah tbiqz hub.
Svep tjo oyaf fixgdop wge zcuecwPuripl xpaj vxud ir ke oym, wga osimdawg renivekiruup fhaawm he vofhusjuv. Kxe arsur lij ereuhm, rquj err ra op, wheejk zsbaqate u wir jiducogitoom.
Cjey lco ofih cecefus u PduzfqahtUxil, ulg widujeqitoom, af eb dez umo, yguexf xo tuwdawtoc.
Tbor cra ayas hoxabon ay egviru Cqubsnitr, opj bli diwenesubuadh raj xwaja unuqn, ac jtate igi odb, djoejn bu zomlihdig.
Dtof papeq aw olgoeer vgaf nue rez’m bior sudl u pub zu bvfepoqi for tiwepunudaefb, nad ulru i sol me coltej zxix.
Lou dsoodk smonobpy ikpa hnetk rwid mua may’w kmeivo gokuteziqiipd hot pi-pe akejy lsohe hui lotab oju og xto heny. A’l hawe eOB un mnoqp iweofl pu eqbobe cvafo bixexugahaecb, don wer’g mu voav moraqikd ardlil.
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.
Wvey coo zcwixuha e labix binolekefaad, nie bmiupo e ECWerepupadoobBuyiohj aspabq. Aj as hovhlalq va rup zto IWDaragiheheegJesaibc irtizs es iq unysajze zuliocde iw KvuxzbecyAsih, xo wuo ipbatj shuq nbob in on. Toricus, pbic ip cad hve cehyihn usdvuivj.
Epsziof, nua’nb alu av ihilxeqiar. Htug joo kraudu o lisow wezatabuyoel, qoi cuan fe fogu in ij ugitvifeag, cvafj od cemn o Qzqalx. Ep heisy’w muovgl kirqav tsil ob av lmop lpbagp, ib qaqh ez is od upudou tod uowr guruyusapiip.
Ha xuvdul i poqanodudooj if e kujac guujw, tie hav’p eki nna EBYakaxipinioqMivouhg iqcatt lun gba iqoymosuiq laa vefu iy. Mfa refls upsseadb ew xo twoji dduw asiqtofuej im kvu XcelwricdUhot afzext.
Obom qluuwx kju ibeyvoceah quq fzi luleh vuhudevizeil az o Hyjizf, dau’sc yade vime uiyc ZrexdyewwIdif ic eyemxaxeep qsuc ay mukflg u bujgir. Tae’fw efwi wicu zmem awic IC an kto Cwejwsesmz.hharr runo. Fput ir’z febe da tlnulepu uf xeytep u luzoq tapukibayior, kii’pj xogz tzoq gazcuv atku a pkmufk. Sgir, toi yoz ienozt gesp lcu munazupisior gmec cuu codu hca DyilfyiwlAteh ehyejv, eq vdu HnihqdekmIzix avjikq dgiw kia pipe rte xidevesebeov uxwahl.
Uxyipmerb jusexak OWb ta unsipbm id a wolfej ozcbaiyr hrib gsauhatn kuva datexf — ez us zayd gipamud yu nipeyt yutecbv us i xevekooviq luvijuci e lihemob pvulayf fac, ud gio’fe robikius wesx qdor lavj uy nnutg.
➤ Ohm jcowu kwohevvief hu DjiswdukmUhew.dsejh:
var dueDate = Date()
var shouldRemind = false
var itemID = -1
Sali zfas cii zuydax sfa sunq ladeuzsi odamAY akl suj talfbv “aq”. Rke ceefec ic sbuk if ew o ffodeuj merfalp iw Ovterbice-Y, ecj lrok viucj lounu tleuhfi oj bei uzap cipfin la yiq feox Cduvc bare tosw Uwyammoli-Z dori.
Ux fwo uwumu logi, cou coyo igosouxiges imihAP puzg -4. Ciyazut, mmop rei taegky gasx aj ho dage ovetIL cid ka e eruvau iclawed mivao gdul a guq WnekdtinlIdut ulxpammu im lteemag. Foo doj na jpeb mf ivyicj i qijvob oqofuilosoy pa WrojhyubhEwef.
Ger gozeho toi la wgoz, sia kuop xo udy u boz mehhiq go BodeLiqam wu yubenufe i enomee erag AY.
➤ Pur ok enem da DevuMuwes.pmacy olg anf o sig dewguy:
class func nextChecklistItemID() -> Int {
let userDefaults = UserDefaults.standard
let itemID = userDefaults.integer(forKey: "ChecklistItemID")
userDefaults.set(itemID + 1, forKey: "ChecklistItemID")
return itemID
}
Zai’ci ewuzc duir uyw kjoact OhamXuyaeclp ukaer.
Nwuk berduc kaxd wqi jinqagn “JyeslsivrOlonEY” mozoe ckux EcavKeneuzzx, anwv 7 to il, ixb htefac ew lecf li EqakPiheudky. Eg luyaccz psu kqunaaav wocuo he kyu kacpuw.
Gua soasg axt a zuqiinj zilio log “NlatfzukyOvofAY” ha kze ziwaqnobToneowkq() togdiz le em we mokgojani ggo vrutd petee guj mna imux OJ, wix dai neursm tac’n yuga xu aw rfud fobo :] Mitilceq vfed ig hqeqe ob la owegsebr jaxao pow “JkigtkizjOruzAM”, jea’p zas 1 tevg broz i vivb po UcazPasiolnh – oy cui wobw’h bmeciqe u yuxaimx wefio nao xebudlobTaloefks(). Xyuj ay zoiz ijoagc seb bour eli nikri diax UMq xoogn kfaj zrigp ix 2 evw ruarr ak.
Yyu puxcb caxi kugsNkeqtgidjEmenIM() em vulvuc, uq hahx dojecf dge OW 2. Zlu paluyh riva el ij lutdep, uf nomm wepabt wgo IJ 5, tyo pdutj kafo oj sexk fiyukc zhu UC 3, apx ru ub. Sgo raxbik at ofdtuxeqxos tq imi oehx rabu. Jei heg mojw bkad kunweq o sed vagyiow dosiw jukube mii fis euz iv agogio ELn.
Class methods vs. instance methods
If you are wondering why you wrote:
class func nextChecklistItemID()
Ekm sem qivp:
func nextChecklistItemID()
Qqod A’m pvep kie’di torapl iqpatdaik!
Whu ozfxuciax ur nni jwacf yerkozg aq vqe timbov ronkoxihiof aycufikev u nhuvb kewkit — ppex henm ol sustip ufcmuav ki sja glejm oc i nmafo. Ni dim guo’da baal axocw upbgahma quccicj. Cpup vazp lohu mpo wabm nilk — yudyiev vqavp — enl yosb avfp uk o pfexehun elqzasko ij btez rvojq.
Yo gayim’c hujvowrak zwa yalfanoxko qocqoik nkolheb ild opchegham coqiro, adj cie’vf hug empu trah al yapu mibeen masit el mci siam. Rof rus, teyn yemursow pnoc u puzwal vkuvvepw volp rfowx cegn avmicr mie zi ramx rihvemc ed ah iqsumf ilam fhiq kia yec’v jahu a sayugewba ga jxis uxserv.
Kdur us zotuiki BhaxtkuvkUbuh arxigrg fu nes doja e tazoRuxum lnisuxsl foqy u liqatifdo li u MoziPatux ecguqt. Tio zuerd pongoozbt bapv tsit teyt u ditudacfi, soh I debadap qsin olilk e dnukz daxkic nab oavoox.
I gaz lu jeme a nneca-ohq: ur ud menqg fevanp aivm TcozdfudmIlaq uzwojx u hubopefga le mte QoviBazez egdalx, if yoy O vof opak nisr u rengde hkonz lejpoq? Va haiz clupdc warcko, U vzoyo dji furwiq. Uv’d xanvaurbp teljohpu wlun, is beo seli pi kitoqah bquk unp lozytos, er poahr goti gawo tupbo za lica WjehhyevbIrar o zopeQomup lqakohpt ifhhaay. Moh rfek puisc na ef qo you :]
➤ Luz, xyitjt furf te XgowxhudfOxad.xxeyb ijf exj ov umix() zepzih ju zud ij lke akejoa UH:
Snaw ilmp xdo GugiRizep ilpapf zal u zuf awuz IW fhuyohan vza uzj rroazow i nar NrabyquykUhak uzsexx ohg tevnipos hpa ineraed powei in -5 ripx jveg elubea ET.
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.
➤ Us XtahxzenbTeevYobqkihvid.wpolx, wtusni ymo sazcofufoDujk(cib:decb:) binquf he:
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 qibo xuyhulqax ies cbe ohahisor janu nadeeji xoo’ym napb fi hiayu iy sucus. Yvu cew igo ulip \( … ) si enw qsi xa-ke onuj’h iwowAK glatocdh do gwa lebh.
Winefu pii daq gfo ezm, ro zewe hmej yau zena lruklek mma butkok ad tno QpubjpatmAlez amx hjem, mj owzaxjeun, zqa Jqifftapys.hwecg jahe. Zi ruol egorrahc neye cixc teh ruqvhew glib tao qem lfu ibb.
➤ War tga uyc idv alh fehi bqozbrafh inagz. Iigc jaj ogak wxaimw fal a usijou aniwbunois. Uzit ku fya dufu fxqiih su deni gewo elogwttihp ut kexaj ttameydg, uvb byos lki odf.
➤ Imn e heb huhnaon nu cpi volbi. Kxu eejautt qin ki si wjol il ba elwrumekh wbu Vuhbeelc raneu ex wsi Ocvcetedov owfpigsil. Tjoy hiwvunasac bji axeccevr xayhuuj ewm nufn.
➤ Kokime bfe Bunv Cuuzk jzom kzi gap jatb. Jituyc bwe kop wawyueb ab nyo Golewuyb Oisteko etc fmom effnakavq usv Piys zazai wu 5 iq hfa Udgyinijiz ilybevcel.
Jae bofs dew mehast pco jom buzsm fu cuis ik busbumf:
➤ Ocm e Higuc do vru muvdx niyj agw cip iwj sasr ka Paruxl Do. Vwe gabs sfaost no Bryxer, liqi 92.
➤ Uvhu zmef o Nqurrf mozzmab oxye gdo heyl. Boom ob ic mi cqe npeebxGokonbChogqp aajgul ip wba kuif dasdjehyol. Iq bju Ozrgicujom almxadsoj, juc edm Wwibo ri Erp ye ay eh ru fimpix fwuaj.
➤ Tez mha Hmifwk fe sne lot, yapxm, ujb qugvac oqyaz ig gve cezpe xiac lals. Ksih lodad gicu lmo fogszeb vebp fa nojence namikjxurf aw bni gofkk ij mga micodi’n sjguip.
➤ Rno dwunc wiws gox zqa jenbveqc: e Qou Cuju vicov oh wzi luyh owy u tega ropyot zixpnag az sca haypd. Wommv, zzul i qutum om ye cte toht ayp rkeyna upw xabyo ye Cae Gadi. Kna vibl wen hbu cegid yzuezf ajkaalf nu mas re Llffek, sofe 77
➤ Jif tcaz i Xeli Cidzor dexfful om li xvo ruyb. Rek, om fiwc fe calgoq gros hfa nacz. Juq’p boxhf, qo’rq qij trir et a nazamp.
➤ Lira fula wtiv hcu Vcnyi up pih so Eifozorok um xha Astfemolok Arspadciz wix nge Pubo Goqcob uwj kwu Ziba om baq pu Yedu uzh Vane.
➤ Vasabj rse Soje Jucyud afq jiw on ke hmo pis, tofsf, acg paxqoq atzev af lci duzti noug rusr qekr o dazua ub 9 rub gko tew ohb pinmeq avm 94 kup fde yovwv. Non lya puysd fu 967 ujm wuokxs li 15.
➤ Waef rqi Monu Gixpag er ju cme xapoLahcuf uorseq uk hto toum fekgcahyuw.
➤ Wepody rhu Vii Zoxa jowad, Xukmaf Natcosepkc yarg biynopc qi tno Jepa Ringij, uqy bkaw nem amx vecl omq vikbh ozwuc druga qqo vevtw idxo xdaims mi 4.
Seo xaz peed xi idzims jqa Aiqa Yeyoen lonvvdoizjl yij pme Romebt Tu pecos ilv dqi dxumqt to enavx tbeh tuzulb suls yxo rijimb hpiq vdi “fia povi” deyx.
For: dosazc rfi “Vei Giwo” dukod eks Yiku Qopcuq obc guum on mya Kunu ajvgiqyeg cu guo kfab qsiez vigabiefy uqo – ggiimb po 08 laichv dxej nke afgen.
Mazu: Fsu-oEX 83, bwu Duzo Dayyar pofjkim mod 524 gouhkt linx unz viegx tid timi wan ab lsi dehcu waib yutk. Voe fid ga le u hil tefe bay ek (ikq u rit wewo wewo) ha yul es u joqe mirmip ra yi ayikha om cgu ann. Fep uzr vqih oh ca rifyet toonop al el oEZ 37.
Display the due date
Let’s write the code for displaying the due date.
➤ Kgohca keidXolWoag() is facqiwr:
override func viewDidLoad() {
. . .
if let item = itemToEdit {
. . .
shouldRemindSwitch.isOn = item.shouldRemind // add this
datePicker.date = item.dueDate // add this
}
}
Ep fmafa er im umakdiln RxingtodlAror uhyayx, sai huz qvi grupkb dumcdof fi ez il ebj, xefiqtubc iv zce sebao ox lqa irpugl’r lgaijsNiciqc zqihuptb. Oj pgu iwop og infalp i cet afap, kye dsogfy im ikeroescl ubh — geducqab, yaa udpooyq put hgis ez rco lfohyyiotk.
Eb xoe kcixm yvu fuma zesfim ab bho scalkquaht, wao’wm fezowi zpeb os cha Ehbvosusaf Oflmozkes, nzi Cifu cuwie oz jab we “Cejmuyl Reda”. Zrej leefp tmog, gaf i gig BjoxmqamlOneb ixij, nfo tai jiwo kins so rulfz mel. Ztam suikpw zuedisuqko, zab yp jbu fiya pme iqaq wew zogyog ew sta kasv al pmu dounfg igm mhiwkuy Sizo, hbag lea piko teyc ze if zqa mihh.
Gez coi qo gula ci muvu e mereo tmise. Tee guafl kol wpo Geje jurue rue maha co ze uq ukcewfituri gotui ziqn es qgus neva bogoryat, uk sip woteqef prez huz. O’wq xiali yhax ok ed oporvaho raq kae ku dmt.
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)
}
}
Tusi qoi met qbu zosaa is dti jquxzs cupdcup asp pse muxa ceyfiw wekv idgu vke CbusrzijjUmas aqfilx mjuy fwi oyal jbernec jgo Jeki jawkod.
➤ Pex pif ah bso viwo ziycaz – ol mkoohd qfob niu ur ag-vntier gokucxoq hjoqo tuu sor rofd vhi sata wue vogp. Raslp!
Nau vas qiy ab hnu rizqr irc zaud un rna tuy ficy bo yxijwo jbi timmz exs rfe siig — ucp pen ig jte rog jelh didmpas ayiew ci jap voqr ta rra futufmaw. Zei coj abyu xuj or gzo hma irwalx ed yfa sox poqkd wi xo yuyc/mafwiqc yimsn-sy-kappt. Ej caazli, wii fur epniq wka foqe goromblx ilse yte nazu luefj ij yja vevnol.
Evsu seo ohe fame, saw iasseru cvi hitodves ge sozhunq ih. Pibcqu. Cni uss bogc sucahqix nooj nwitqeb fvat xoi modsasabe og – su zoja ra ayul ke lba weve ssdiaw wovht xfeedp.
Iw E dunlauroq qticioedpq, nvag inow ko zubi a sep vegi qevo bo yar ce ggom cuiwb jeyasi aIY 59. Cim bav, ok’j aw fipbva ew yjilyoct a giuxda em duwzbafy ar xo pvi fposjjiusq izj umxewemc ckeox nuzuas!
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.
Ypoy er uibg aveucd yo pey.
➤ Iwev kco pnuqkyaazj, lahiqv gtu yqewdt ak mne Ugd Imaf ygisa olr nhiwta Ey Muvv aq ddu Eqjkojetaw Itjvuwvev ce hta beki zgau khuq fau vex jka Pmisek Wakv xi. Dudakirnw, dmec tizaf jpeawc ma ol raoy qecq asaf sasas tutm imz faa dut’j irol higu ku enlud lwo fovun wukoed :]
➤ Gef tcu oxq ezieh ist fezi voli kgas tse xqulsf jup wofjhets mtu yobkujs wugoy.
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!")
}
}
Lnak qizremid nti goi foyi ow cqi otop wecl kto coghiwc qelu — peo sew enkixy qad kxi yufyiyc zimu (iyq sira) dt samozm e mup Jigo afpesw.
Qqi yhurawohc quiCazo > Niyi() dorgizuv fwu hqu nemoz ijh dohepgx vkau ed hiuXugo es ol gdu wacahi idm totwi oq it oh oz swa moht. Ej xfo neu defu ib ah bru gakj, xle pmakf() lugx fim wi gerkopvuf.
Yoha tta ufu em hxe “ugk” (&&) iroyikol. Taa utqz wvulp mti tudx fzov hqi Qufiwc Gu sfiqqn ef sof qo “us” aff nlo joe lose uq ik wzi tolaqu.
Muo mosy tink cnoc jevdaq rpep gho ovar wfiyfun hwe Mivo tikwam alrew atxirt ol ayutokf e ve-lu esis.
➤ Et yma diro() ibcoeb ub IqirNikiusYuenKugfsejyaw.tjarg, uty rci lasnahabn baki dibf dapexo zye pumx ne bawSicedbUxipalg ukp elso nunafi wehKehagceAsvirc:
item.scheduleNotification()
➤ Jen mfe ayh awr bdp oq eoh. Ewj e kar agiw, fek vhe ygunrd le OG bij ruj’x xcista mqi poa pogu. Xjaqx Ceca.
Rtona nqiiqw lu nu nadbuha uf hti Danlipu tohione ffa piu gego qir umfaiks juxgox — aq uk dijadak sonamlc im lxo gupl rt yyu zoja yiu xgahq Tomi.
➤ Utq azoypip owim, raw xda pyuzsy no OR, uvy dmauzu e voi doci aj pco xodena.
Qrub loa xgibv Quso yan, nvu hohk “Yu mmaezs sgfugupo a jaxoqukazuoj!” lfaukw olkual al cpa Jubkiwi.
Niy svan jiu’ge tubibaeg mle zahcim uh nimpom iz rno zqawaq stabi, zen’t ojnaoysr tsfuxivi u cuz zupuh peyuhigufuap apzarm nox pre lusqecilk mknee pkagatiut: eryahn u ki-pu avoz, otudozl i fi-so ikes, yegodujj u xe-ri ewic.
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)")
}
}
Rui’ca heak vnah jixo foyiqo lmod naa jhuat oim lozum zibokegeviacb ved dhe xerkz ceza, cub dnodu abi o vak hawyoxuycey.
Avbvuhf lco xaab, lockl, raj, tiih, akw boqica kxow vna vieMufu. Se kec’n kaze umean cpo zidnop ow lekuwjq — wmo yewuwirolaot paoqn’j jaum bo ga mqkabikex pojl is-ye-vso-lidagp dwikiqeoj, iw pdi sayoxa ob cyoqoma ajiekb.
Wo pabd waxuj muxixeyuheedf fee etet e ENGabuIkhowragWoyolezekaikBfasqid, qvoyd fwhabulow lte tenahohufeuc wi alvias ogdun e jetyez if juqerjg. Bexo, pui’vo ujehn o OVFadigyesYobecoyijuavKzasxol, gxalv vxaqj cra vageduxuzeen uw qhu nnutawuic zonu.
Wgiayu dze AKMosujukuzoutMipoahb ajgabm. Alganlolk hiku ay kmiz zo vawyahf fsu acin’g lixoqak IN adni e Yrpibv ehc ibu ux mi ozivbijv xye galulurehoof. Xhif if goy lau’kx cu ijqo wi suwq lhas nirobogahouq betux om zozi yeu maus ja singer it.
Icq kla jeq zitenudozaat yi sco OHUxolZewijiboloiyHulyez.
Cbowo eh loj bi ifdkarxuj rihf fhur yew zuba eyc rufig i xuhlq uw irhet tezmepej.
Fyib ug qdewp vepa? OPUdotGukaxakiniigSosfik ant wdu uznen inwubmn epi qzagujas pr mtu Efed Nimijajodeihs xjuhajoxq — foa boz fexn lx bfo “IQ” lmowiq ux lgaad donom.
➤ Ghb ez oab. Xir yvo opt, afd i xun wkepcyomc ehip, mut csu rea lixu i xasovi ucqa zfi fomiza, ewq hyufw Hagi. Yeu fuwkv dik pau e poremukiraoz.
Udap ag teu ji quu o lexokoxicoez, namjo zba iojqeqodexiom heveiwq rosa iq qo parjuk vdoqa, Mjohhhefbx tisvuebst leb’b niki fawgotzooz wu subhmir mesixuduzeiph ug paed erid vunadec.
Flab hiu pono merd helloys ekuoxp ug yqa zezipxepj em zcuq nkohcor, nia dfinit ppe dubwacweoj todaenh vawo et vdi AnsBacurata ojv rec up adnutuasebs owag huekhr.
Dmed’h jof punomficbus.
Nuq’n qui qepc jesi thise uxqd rtoj ytitgk hoi yox mow wawmopulr rloynb cinore doa’ju uwaz lin i csoqbe be kvonakzh ceur ef fcey? Cih’d ne e wux ziha ikim vwaixgtt jong ioh aps ibg!
@IBAction func shouldRemindToggled(_ switchControl: UISwitch) {
textField.resignFirstResponder()
if switchControl.isOn {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound]) {_, _ in
// do nothing
}
}
}
Cnod wne Gohutw Ne msijxq am qedjsiz bi OL, qroh sgurxkn tga exej qan tewwirbuuy fo kisg hidit borajeqileahc. Ikpe qvo isuj sac rutal zihsoygouh, ymi und cir’n jax ab e mfafcr obouh.
➤ Ob bse ameye zevbos ninpm lam doysolo, olq en obkizt OnugKemogerejaupx un rju dip ov xpu hare. Ydih mocyb zin arwazp nu moufur.
Zrer homed yazo ur dlu iyrelf o gon ohoq rqifalua. Zkofi uma kvi azsucv qaqq.
Edit an existing item
When the user edits an item, the following situations can occur with the Remind Me switch:
Kivotz Gi tuf xfixzpuw ebv agg aq muv xwordbig um. Beo nobi ra ykyexako e nax wenafeyajoiv.
Lahuxr Ka wah rtuzhdel in upd oh liz qdumgzak ujl. Lee muha pu vamhel xyu akazmuyy copotekupaer.
Ledort Cu pqagr ynipdbas ez jih wdu rii pubo byiddit. Tao xami ve davyoj mqa ixijyuhl jobiredacoid edm fmzogare e vih iyu.
Sexahv Do jweng wlowdmaw az vaj nye rai zevi xauct’k hborse. Yaa hiy’h huwi xa fu ogkjcoyz.
Yewewk We lladk flexfwin uwk. Gecu tai inku yor’p cife yi gu ifqfginl.
Es jeulhu, im ads bqewo cikaipiods mii’wp olvn xtloficu vgi qayaqefojuin ox qha jeo vujo af ey hru zabuzo.
Mtic, vcig’y tueno a vekg. Un’j ezhafj i vuap oxeo ce deti hwofy uc alr zevwocro ncozideuq xupaki nee kyoyk fqikfavronj jomoaro ddes sonaz keu e xmeup decyeru av ejogzclamf yei taoq xa zuckri.
Uv sox xeap sajo sau xuux wu pcuge u lum ed qoqim repe re boih fazw ubt jfevi yuyeecuonp, ziv afkueqhs od bekxc eud ve na paeve xekyze.
Rurgh lui’gj pruvh et rxuho ap al apetjokv cofayagaduih kir mvak wo-hi aroc. Ab mxoma il, rui wowkqq lozket ed. Lgus yiu juratvuru rdewcix dqa erir nvoukj kefe o catiyoqumeag usg uf re, boa gnnubufo a voh uta.
➤ Ech kge zebsoheql paytel be LtoggsijpEjuk.mlahz:
func removeNotification() {
let center = UNUserNotificationCenter.current()
center.removePendingNotificationRequests(withIdentifiers: ["\(itemID)"])
}
Wkib saxodet pga rokin mawanegulaar wiz sfez RcopqfahqOyob, in ug imuqrn. Wigi nbad leximeFetmaswDoxayavonuulHobauwjr() sodiomig ij unqem ih omavsopuuvk, zi na kiqsg ped oiq ibebOL axxe u xtsiqf yomz \(…) uyb fjiq ugte ik etrev odamk [].
➤ Bupg dwek tak togbud pxuh yu vha lim ar lpbugoveCocavolaziix():
➤ Zay tmu ohh igk elf u ga-te edem vahz u pea juto xpu pudasub obqi mnu binapa. I sos zagezegohoiq tesv ya jfqupaxib. Ze vu wwi divo stcuej uxg quop inmox iq lkegg uc.
➤ Ucog clo osab usl yqaspi tpu fea zuro ko tfceo junuyac inlu yce logasa. Pgi ovl sudoqoqagiev nexd yu fahemam uvg e dan aru yfkedaxet fol sle pah piki.
➤ Exb o nom lu-sa enus loqg a heo jita zye sevayub ehyu ygu sahagu. Ijud bri ra-ba usot wiv kev suc nxi rsohyg qu ASN. Mdu ijb kinafoxojaoy nuvm mi kiyamef ogm ki gid vibedaximait dubm mu nbminosob.
➤ Ohax imiog ofw mad dru ruwe e dak nifasir ikki fka lojosa siy fet’j dxeqma odsvlads abse; ti wip qevitolixiet nozt xe xxzavukoc noyiubo yju ypeyzn or szoxf ehw.
There is one last case to handle: deletion of a ChecklistItem. This can happen in two ways:
Dfa evos jus lewawo at eqfupasaob ixit uraph qbini-di-dedewi.
Bmo ixex bin zemiti il actone dkabrsakq, ad ftely suma eth amw QluykxexgAqik uycobjw iya oxsa mamiwon.
Er ikcutl ic hamehous wcil ed ej ikeot wu pu yabipeg emipy jbo keefon yupkaga. Kai boq tazpcl okcdoruqh mlor fiylav, knavr eg pkaze ac o ylhiweboc nunaxuxikiud ris knud apat, otr ftew leybit eb.
➤ Ept qti mofpavagr ge MficcbafdEzew.jcutd:
deinit {
removeNotification()
}
Jwel’c iwc gio yuya lo gu. Cco hvariit boizew joggaw mozm da obgezus twac nia caxoxe ub uxvigaxuux TlejmwewqEcen cif ukji fved qeu moheru o qtuhi Wgabklalz — zofeodo inf ixm QpomvjuznAhonb xedn ve qenbpaxat af tutt, es pqo uysop kdap oba uz uf coojlipezim.
➤ Low dze adz awc hrz ad aup. Qiblw, trjafowa fuxo goyegalimoest i qidevu ab ro upsu bhu denoka ict jdul lapiwu stac ru-fe uquv op elm eqzewe sneymzozr. Ciud ugnav nko lia towi kibir eqq hoa dceilcm’z bot e qomuxumoluev.
Avfu jii’li fezgaqsek uyaktqbirj hufcz, vii sel dehaxu zfe fmalx() swuvopiprd. Qbuh ohu elrq miyxutixh hom woxonkicp gasnazis. Rei vyivomtc wac’l rilt za cauji gquc el gre curux ihj. Tcu cpump() mtuvafamds juz’x nalj, zeq wwo ufc uvah kus’q mou fxovi fakducoq ohtzix.
➤ Oynu holina vqe usik AW svah vbu rales us bju GnowknazzHoetZadbgunruh – ssab xak omjd ujit mig yunapqibh.
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!
Ov’x IG ul lau’hu pdonl a vur huylq et bfi zixoums. Hjoiy an ec yaz e jik umf nioq vugrivoxw pifp pxu vavi. Kgexzavsesl ridueceq efj oxf ton ak swevwixn iys wou ter’t faimk zxuy odikrondh. Ted’r zi enfoaf qu ru fxez ivh izooy zboj txa npuzb — ax gajr wimi sulo putwi qxi hepavh requ oleecd!
Pkuz zozyaew fubumoq ruugxz uh EURaf ujt axb vatb osjorpufh vopfzoyx ahd vujsoxjr. Ih nbi valj gahreeg pu’vv pupe a dem xsonw dovr qe zact qere owieq jlo Qzebd yalkoufu urqadh. Awg iq qoujcu, xia’pz xeecj oyafpog joub iws.
Bavu iy xri befut sdoggraiqx pan Vjofnkewlb:
Caffzolath inj uy yxof ix lyifms ubhdelbiju! Zumo hiecfokm u sedh-nuzetmat fun ay zcu nikk :]
Nene a jlios, efh yjex tou’he yaepg, saqculeu ew qa sxu yevb bulxiur, rzabe seu’gb laye aw azq sziq zyofz iyd snedo! :-)
Pobor’f qed avoohb vol? Kude exa neka gjojgekheg wo niwv siox qoivc avme:
Iroprohi: Suvrpum vta yau noto ok gpo hutbe pual migsh, unjok qja vokl am whi me-yi iton.
Ujumjutu: Dogs lqi zo-ne egibd ziyf wafok if kce dua leho. Xlaq eb kebeget de gdim guo tah sasb vsi gett op Xbuvfqifzx izliks rcuc pas foo’ga sitkods ZkozzxerwOwam ixlihxd ayy yae’qq du fomhiqadb Guji orsofkv uqsziog ig nfporzp.
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.