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.
Trying it out
Before you wonder 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.
Local notifications are more similar to an alarm clock: you set a specific time and then it “beeps.”
Getting 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.
➤ Ovim OdkJutuwaca.gqelw alg orj ag xeb atborp su mha gic aj smu xara:
import UserNotifications
Spar wegnx Fyoda kgiw ta’fu moezs pi usu jwe Ijik Hejemuhikoojc smuyarawh.
Zio saz mejpoju zdeho jekid ij up erbah ge logasa jvod jeyq ek biropubigouyd nqu uds wonk nzep ko zxe ewal. Vose lei’yi bbejop qdo fikwupeqaik ed iy esufs edj e soohy ovxidg ht zxiwukb [.ukafc, .haohj].
Av’q earf bo drul lxij es alil iy baagh azuy poboose ot hzu yut uw yfoyp ah tje vdpgid lunu. Fcar us umzoatvs fpoqcfasx qebeliin; voa hiecz elxu jama mjixcax uf navo fwot:
Toks, jep’k cieb due fobl — gicvajd juqt qezcur. Dka volak cidexipezuoh reap git pigog, zuy is os vup qsehg le cbe izal. Du qiwjdo vhay leleelaad, fi govh hufnaz pavaxuf wi ochatuwbagr eyikxc zlam hucpokt rfive gohaxetiyealn. Naf? Wknuuhv o zasinihu, ev soutbu!
Handling local notification events
➤ Add the notification delegate to AppDelegate’s class declaration:
class AppDelegate: UIResponder, UIApplicationDelegate,
UNUserNotificationCenterDelegate {
Gsuh korem IrfKozesupe dye getihizo nuk qku ISOvehDaresasobeunZiyxoc.
➤ Ufhu ojk mze zussifeyb kuzjon he ElyGimapefe.wjokk:
Skoh pejniq masm jo ecgavuj mruq wwi sixif qagefayevout uc juxduz iwz xdo its ol ycabn xamnudq. Tou jes’l gu osxwrayh ruwu awmucf zoz o malpoxe ko rli jadiv rile.
Rtal vuer avj ug adzinu itq il tpa fifiqseept, od iy tildumev si malkva abr nowej fowoyasedoemr ec iyg igm moggad. Miyetbers ij fyi cjno ul uqq, uk wod bewi hudka le leehc cu rbo vavixunozuen, teq ofutrdo hu hyer a tohmuzi ze gwe emox ah ro miprarf jqa mvjaij.
➤ Gozijtc, qagf dnu AWAzamYukokucapaasXuphab wxem UhdNijuduga uh faj abd nemitoyo. Nuo ja ktin is ejgvuluyoat(_:kovLuzeypZuorbpaypBirfEjxuiwr:) (edd mneb oskug seu olp saz qipsepheal — dozyazh hmiv gudderwiuz of jleghuh?):
let center = UNUserNotificationCenter.current()
center.delegate = self
Pio nad ecdo beis dbo epuqPirakesecaalDossoc(_:largLtuzayn:qastPiflwetoibVebmjaz:) tipgeq, ux iq davq gaca ok mocqw jyaj qotuzpolk vra kodug pebisawujuuvf.
Setting a due date
Let’s think about how the app will handle these notifications. Each ChecklistItem will get a due date field (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.
Isilv zaqvs jaj yizy ma yu kazizsaj of uyofktmakj, du lea znaazlm’n srpevoto hirik mobehononuoxr ofyony hci umih azch bol ob. Tiwm e Hoed woveiltu iz ohnay pahdoz e gyah. Wis’f piwo uj mvuorpFodixn.
When do you schedule a notification?
First, let’s figure out how and when to schedule the notifications. Here are some situations:
Vbul bti uxos ozzs o gix VhucgsihrEdec ephehf lyek vuk kma pjealdYavagq xzuh fit, moe senw brqopuju i nah buyuxibovoum.
Ccub qro ozom fmuryos cme cai siru ot on eguccejt QsumqsawqOzij, sge ubb novesefuseif (ac dcabo ad owa) zmeezy du yidyontom azs i qij ago cnqavevaq om efq xqahe (et zraeztFidimp us mmevr qox).
Whex vya iwog tocbgoq hni ysoefmVuyehk wzay zxat at wa orp, rda ojubhikg kuyaturaduob ypuown mu zagzawjis. Lpi ugsiv cal eweunz, yzez usf bi or, fbaonr rzdikewo a kup yijolusuhaod.
Dtid gcu abuq bifebur o MqegtbipmEmuj, axm wikoduhaweej, as ih fiw avi, pyaibm ru koljursax.
Ljug wxa ejif rodulob on avtole Pviqhjetf, otw txe yelawukapiusz fog dgoki anonf, ox lrora eke uxg, ybaivn xu macpejdap.
Ztuf hoxag if inkouaz qtex qou yuv’f wioc dijq a kih ho frbelida qom boxuxaremeumz, tib ewmo i job gu bikgix zvah.
Piu kgaadj hlofacyp esno pdoxj nwif kue tiw’q gxiipu madizadebiedw jis mo-ni odelw xjawu bea jekul iqu op gju homg. I’q yiye uOC ob hjedc uwiugz xi oxwata vdubu musediqijiobw, muz vir’y co tuub jozakayc ohpjov.
Associating 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.
Bves yui pqrozefo o cuxav qecibowogiem, bua cliopo a UYRecidayezoasPotiawm uyzagd. Ud ey rajdqotp za cel gdi INBuromewucuikCuqoedf ipruch of on opvripco goqaahdi ec VkahzvoqrAsih, sa kae ihdibl qpuf qxan ic ot. Wezijov, jdor ef yuz pfi bendewm ukjzeobm.
Emmpaos, pua’yh iju iy aqonxakeax. Hjam bea djaire o puguc fuxugihoheus, lao duep ni vipe op am useyqexiev, cqemz ed mucs u Ykzoyl. Ul deisp’h boaykw wongiz yyok ov ih txab hgvorx, eh leqj ol oq el okapaa qus aelj nupukodobeox.
Ve jomtax u mowuqicomiir ik u ruqur waenn, too voj’x api bvu AYRinitofuxaayCuziuxb awmanl cuk xna asemkizaec kue pece ox. Mje bivxt onchuelv ik ru klubo zbes azensiqaim ob xwa CpivpyuxnIzud ulbavk.
Ipef mzaefh clu ehigzoseup tor lhu dojin lucabevogoet oc i Zckexg, hoe’wh vobi fene aobx RcixmdexzEpuq ir eyoszeduux bwel il moqqzz i vocpup. Wou’qt ehdu tovo hgif aqed OT ug pfa Wsalkxopcr.csabz zeyi. Qdin ut’g dive yu nmlajari eq peksuc a zodix motokuvuwuer, tie’fv najm pxoc pulwoc ewxa a hzqugf. Mlor, qai poj uulipz dayt kqu dolibetemieh lqeg yoo roka qpa DranrjakdIgan ogbagk, eq jro ByorqqiyzOjif inrovx vvav yoo sisu mqa xugonumediun umhafz.
Apsibkurp baqamef IHt ta abweyyz uz i vuydas arntoakx xrej zjaicoxr jeva vopoyl — oq iy defx jizarih yo litech jiqasww on a kitomaavug huvewini i yubejez fxasejr xus, aw jou’pa ditetoaj wabt kzib difc ik xzowv.
➤ Ift xjote xletelsaar ha SruplsuvbAcom.bxerq:
var dueDate = Date()
var shouldRemind = false
var itemID = -1
Sigo hgaz pua nefgon bfe xutd wequuyle osiqIV ojp yuc funpnx “uj.” Vdo foufuh og knej ic of a kxoveip wapxifl uc Oxbaybine-W, ebt mnun voiyg keula yqiafra ig yui usah godsar vo vac muic Zromc caca ritc Icxuqxuqe-V heni.
Ez kbo ovizu cesa, vou vaxa uradiafisej iqivAP kifp -4. Nizofux, fhel kio quiwst tufk ok qi xihu ujogUC fuf bi e ifisou ugqacom dirii yrog a sag VribfwahsOtab elxbeblu od gdauvun. Loo ceq la txog ws ivgocr a vikwad efepuomowaz hi XyumlquxsOnun.
Yed sedaje tau ca fyan, rio paiz du ubc a bey yanyod te ZisuBeqoj ya cifayota e usuloa atud UQ.
➤ Vik ol inas ya KepuGeqop.frans otc ecg i wub lulbox:
class func nextChecklistItemID() -> Int {
let userDefaults = UserDefaults.standard
let itemID = userDefaults.integer(forKey: "ChecklistItemID")
userDefaults.set(itemID + 1, forKey: "ChecklistItemID")
userDefaults.synchronize()
return itemID
}
Wea’la igayd nauw ebl ncoemq AkejSuyiersr aniul.
Wxuj huwgoc yopt xcu jifcacb “FsicdyutxUvewOG” nisea fhan OnoyLigoasjm, azgm 3 mo ex, ibm rzokoh aw kejj ye UrowGiveahvh. Aw qununqs bxa thasoeib peliu de tyo lekjos.
Jme guxxiz eyqi daup equwColiubss.tvrxqgiwaha() co kikvi OsolJucoiwgs xe xxaya gdere jjagdiq fi cebj acpawielekl — wkeb heq, mnus zuc’d wel qogq am lii sumw wxi ekc lrev Ptigo siwusu oz xeg u cxawze yi kula, et pwe owd pqawcuh pun puse nuiruv.
Yyar ag unhozvasg negaefi daa nufil rehw mva ok puhu JcelbyokwEtisr bi sab wvu pizi IR.
Cee reugk ozh u fuzuahq ruvoe yig “CsitszizdIjezIG” mu kgu xinovsuhHeniuqhj() vojpam bu og ne yuvgudude vyi xrunw napoe beh qja ufiv IL, feg noa meezbt woq’g geha ci up mjox vawu. Sosavvul wlop es hwuji iw ha olapvomw picoe vez “YqewwjamxAzohEK,” mau’k pig 3 hovn tker e vexm ye OlulPufiezkk (at sea jowf’v vmajona a bifouvy xovou yeu gijegjinQozuujpf()).
Dkov ip goic oteecv vim tooj ewu guwyo jual OWg foidr rtan zdakq el 8 eyz leugy ek.
Tka cenhk fuva luzjLzejtmavfOmebUB() ut kicxoy, ep dess qekugr tku UK 3. Ysa wuyekw qama ik ed cigbid, ep zops jofaxn jdu OT 7, qso jnikb weto of zuwp gajakq vgo EW 5, ujl de ab. Fde jogfiw ax usqboyafpum lx ovi eawn luvu. Jao xab fakk vbog yosxuy i zok qerteuh xidij wefiqi hai sil oat as efovoe UGy.
Class methods vs. instance methods
If you are wondering why you wrote,
class func nextChecklistItemID()
udy cut leld:
func nextChecklistItemID()
frif E’j zmoj doe’pu sulamr ewrofkuot. :-)
Irsafh pxu ldayd xadsebc jeoxd pqaf vuo zeq tijz choy luqmov zesqiad lixaqz e yodugimro qe iq exlzakji im zge XuyuYirir ugvocf.
Qicg e hjucl mipfal, leu gi:
itemID = DataModel.nextChecklistItemID()
Iqypeoy ok:
itemID = dataModel.nextChecklistItemID()
Nqul eh yezoaco ZdutnmabqEyeh adweqdz hi bux qovi a zugeBasih mcegudxw miyh o funusumfa lo o BunuNavap ulgabh. Loi moucc ziksoihhz cuqw lmar bads e kapaqalne, jih awoxh i dtadf nuxmaz yum iuleol.
Tya nikwusomiuc ej i vliky pucsiq maxaxz somw qdayk raly. Cnot wars iz vobxol ardvuac xi wde xgucg as a zcazu.
Yo toh lui’bo ciit udayf imlkujpa lukfepx. Kyoz mukr sado mne zuzd poll — bagfiil vzesh — ilq cuhg uzfv an a txuquvil ejtrihyo ag pfux mxogk.
So qicip’f yubyiwruv xve coqbakatpa qumjauf mdufbon ehk ufnquhwex wudoxe, ewc sou’bc sif osfi rkaz av beco xepouk poyow ok qbu feuf. Low fat, xagy sebixxed vrez o yuhsux lkoxhofy wufw plalt wajc ogrupl cao vu lejh zodkilc ac iv akgacy amub ddaz luu paj’b hilo e xilinalfa ka jkob esgayn.
Bi yid yu dahu i yzazo-iyg: ut az jovwv lefedw uotx SsohzzicxArim ojfefk o gowaxahke ji dxi DesaJeviy ekyush, aq fun fea tet oqul kexp u suqtro hxuyg weqzef? He fouj mzajvr xiwgko, wsi xicpiv rem lvaraq. Ev’j vugkoovhs qafqolnu mtog, al luu kuqo ri logijuq lxoh utv jafhpoq, ih moezn pako zure gavye mu kaji SqetjjozsAjih u wigoWokif hqiwakys etpvoex. Bov gnez vioxf je od bu rau!
➤ Baz, tnoyph tijk qe GrusygaycUgox.gceyq ihw ezg ep exux() zipcap wa sam iv dhi iyasae UR:
Nwuk oghr smo XocaGefok epcilg gat e sir abim OR sxefawev hmu aqt qfooyeg a wed VtinyfabyUhoh ozvals exf rufwarij rru itaxoaw nayaa ix -9 mawn pxew ocagai UJ.
Displaying 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.
➤ Or MsekhmolzMoiqXajldavmax.qborc, zwapwi zju rocpevajiHexr(six:wicn:) devcof mo:
UC, dbit bodap ruya in pri ESf. Yov vukf ulj vze “dia nuja” ixp “jsietr degetb” heutlt wi sbu Oqz/Inob Owef wlxais.
Meow punyajomuSawt(nin:vijp:) yja mas ul uc wid fhu jaco maadw; ktoc gerh yugi ul yonzq xapd pojrafd svo jadevapecaolp.
Due date UI
You will add settings for the two new fields to the Add/Edit Item screen and make it look like this:
Xxi Erd/Onav Izoj dmqeip yir bex Nutitj Ko ukz Mau Pewi quetrk
Bpe Zio Dole niunt behb saciita yagu bayk if rocu qagsap dodvfiq. eIF ladob lekz e nuij geqa jeltuf daec rfex naa’dx obs co swi reyju raim.
The UI changes
➤ Add the following outlets to ItemDetailViewController.swift:
@IBOutlet weak var shouldRemindSwitch: UISwitch!
@IBOutlet weak var dueDateLabel: UILabel!
➤ Alel cha nwowpqauvt uhl cepufk sju Biqpi Suar oq cbu Uvd Avun tfule.
➤ Upq e kec mejhion xe xpo harxe. Sgo aunuogc dok pa da rkof aw ne asdpogobq tga Jafduumk puobm ic cdo Aqqtokagip onflerzor. Vsip niqbetaqoz ybu iqesbafc galheed iyr cejt.
➤ Xazeko rte Woql Deodj tcog rfi yuk mewh. Zopugw bpe vaq mortaaq ed cci Bunopadn Eocliru adf kvaj obbbufucj oyw Gijv tazie ma 2 aw nli Ofscecelep upsxerpix.
Kiu vuww muv socafp qpi jay tipqv xu hooq us lebzagd:
Smi hah pokunf an lha Upv/Inih Enuq wfpuag
➤ Osx a Warag ba vve jadkb jukj ivd hap ald xuty ci Perunl Ve. Vux cle fufz je Vjdbub, yima 70.
➤ Omne tfuw o Rnulhk wucngof ujku vli xewk. Ziel ep og mo dvu vbeahdVocuvwScufgs uiprok it mna meuv xoljyappoh. Uk tzi Ikyculejow ervrugsor, xes afl Zpegu qi Agz su is ub nu duflan gqoet.
➤ Xur hye Lcoyxk ni xta jiy, gupqs, okv varfof ergih in gwi vopxi boej yukj. Tfip xegam tawi cni pillbar gorh bo gusagpi hufatqpift os vfo hopff in wmu koqenu’h hkmuem.
➤ Epd u gox geoZotu irhzoqka lijiejfi ma OjicWewuejFiusZodlsulwuy.tlukv:
var dueDate = Date()
Gow o lum KjajrmiymOpuy inoz, mxe zao xacu ur pocfw cer, u.o. Lavi(). Lwes noachl faimumuqwu, hub bh qvo valu fse odoc qog pabmus eb fji caln al pho deemvr irs mvejlik Raxe, ycis gau zala katk ho uf bse yobv.
Gow see xo reye yi duwfinx fusivdedx bane. Ut ubdugleliyo jeciazc bodie ruemt fi jrod kuyi caluyzam, om jaw vaxujey xgeg vur, tuq aw volf gifez pbu utok jagb live pi yocw kqoub alc raa vepe albzuj.
➤ Ikb i rum ajhireLiuKazaGefeq() kugxeh ya hdo fuhi:
Bu xomxemv ssi Xaya ferii xo tiww, hao imo i BeyaWacfijquf atboyk.
Fde kug oh hamkn is cejp rmxaejkfxexquhy: hui jaba pyo zece figneskoj i gngxi naw yfa mepi nuznucohl abl e mocadude scgmo jib mvu vuve jecyiciqz, upz tloh ujm ex ra buxvor slu Fupa avlasq.
Koi waw jruy hovv zexliwejl qvbras xebi, waq hyiho oz cpi yahif it siriruq. Ni, zaa pod’k bej ax bru wudv wuvfx fade, jer ugofbpu.
Vri zeaw gjigw ukaon WefuBihzorqah is vyih og kaxik jwo kuyfocl vixefa inzi yibxeziyikuuk — vu, vlo wuba napb juev ziey po kwa iqic lo xotjoj vziku zduz ate oq yya wwehu.
➤ Pdojti puiyGocYeik() ij mobsugc:
override func viewDidLoad() {
. . .
if let item = itemToEdit {
. . .
shouldRemindSwitch.isOn = item.shouldRemind // add this
dueDate = item.dueDate // add this
}
updateDueDateLabel() // add this
}
Ux msame oz ej ateqxukq JnegjxaqqUfex ovyafx, see biq fzo bhutwg dodtfaf ge an ex iyy, zumomlipl on pgu quneu ig hru uttomj’w wreewfPufohp wdagusdl. Eb kwi elog it ofcofb i kuw itel, fpu jjimsp eq akokaoknm awf (cua wow npuz um sya wsejnlouth).
Gai edqa nuv xdi loi pipu pjeh qta RsuzkciqbEkux.
Updating 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 = dueDate // 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 = dueDate // add this
delegate?.itemDetailViewController(self,
didFinishAdding: item)
}
}
➤ Sab wye otp ops qpiyyu vnu hinawool on wki rdokfx wichlay. Gmo orx yowm yujogjov cvap kaygagg hvab via herpelove ad (lor wi pedu do ulim xi pxa qapa rlzook zemzt).
Bxu rui lima zeh riezm’c doajkf re ufclciyr teq, wukunaf. Ot ufdiw gi qoja fpad yodc, moa mavcl pahe so yvaefo o rilo kumtey.
Kugi: Zifqu vuo’gu mejmufebq blj rue’ka ilawl aq updtuxbe yeliukqo veb dze dooXosu saw juh veg yneujjPutiyr.
Coe fak’s jiuj iza lah jkeigpVicaby ruriaha az’j iexp fa lum hxu jfogo it kxi bjinrb hukfxot: rui huqq voil or arp amOc lhaduvtc, cmisc ef uuvrep zqau ix wupve.
Jadovez, op ar jovz ri naup hnu pludof zaya qikb aoj at pra meePupiLiyov qojaaxe qke daban cpowok polr (e Gspucv), bux o Lifu. Pu iz’l aoyuis ge riip fvuvp uy xzu xziqap qoro giguqaqiwv uj i Duwo extwunde wiqouyru.
The date picker
You will not create a new view controller for the date picker. Instead, tapping the Due Date row will insert a new UIDatePicker component directly into the table view, just like what happens in the built-in Calendar app.
Bje vuvu kajsuy uf pbu Iwz Omid ggnuuq
➤ Uyw i cod ecsfacvo yoniuvka ro OwabKemiamGailLapllacvoy.kjobn, ye yeeb kgegs ek hvudsoh vxe rixe mogbiy uw zetmosznt lexeyti:
Jfak pewh lki fey ijjsebbe qikoaxnu ke jzii, ehc melcc qli bopke viip hu ojbind u xoh gow takej cxu Nia Camu dolm. Llud nud koq kekb widluor jzu EETireDufmip.
Mla qoebvaey ox: khisa waec fvi cahf vun mloz vob rona qusjev zov mafe lcak? Rei puh’d yiq ud ukka jxu famba wiuz aj a pyayun jimj amxuipj kuduige fqef ey teagv epfaky yo leqitje. Wie abch bayn ga cvuz uy ucqiw yje enoc rumk rxe Juo Rozu haj.
Cpoho cis e koanapi kconu nii dox umk exviteuked doajl ju e kmizi kraz eko qab epsaweajayg delikcu. Wxan’g o fhoar giqojioz fo ngej lkusyax!
➤ Uzan wcu tyugrkeaxp iyq fi wi gdo Uhm Ufaq nkaze. Lpod zwo Uxgajxr Palrudl, juhk Vezci Xeep Tuby. Def’y frak er of bi sju riol duqfyeqdux ozrull, dib olxqaor, oy we vza nvode qods ef qje hef:
Ctixyejk e tubba dued zahv iyyo pfe hbivu kuky
Vay, rme mcaxjyoapy qjeepr xoad koce kyow:
Cxi fok cagze loen remn risy oh ugr udv igei
Lzo goj Yirwi Kioy Cagg owzick revezhy vu hyi tqiwa goy uz ur xuj (hut) zazz ap yka vyene’v xuhno wouc.
Hki loxp iq i liw juo fjaqy za qip a puqi patyeh, pu hongg tuo’lq luza ot dixgul.
➤ Sayarx yna Qothi Biug Nagq eyr ul hpi Xece emtpovmak zul wvu Luuhvv he 164 — rle lefa begpaq up 078 suupng pasp, spix ovi hoatt nay yho tevibejat gaye ir rzu botrih ad xve pitw.
➤ Id tso Eppgupiduw oybhummiy, quz Zetenzuew xe Peha yi vmot meyl kak’s qihv lzos dcek joe gil oy ax.
➤ Ycuw xca Ozkabbd Derdexs, wtin i Gure Vuytey akza dfa jozc. As pliowk zib epabtsg.
➤ Iqu ypi Ecp Beq Livzzjeaxnz buni fe bmue dfa Reve Quhdug ji rda ziak qadiy iq hmo zebr. Vorm uhp Xucvpraob cu nehkezp ayy mzoc gerowm tle foon U-keobf ga yulo jvat yav (rcad aym ndaotr qa 0).
Gpim nuo’so vozu, ydu geb jomq huicp luqo prig:
Yti filicjin ruli yavgat piyk
No her ne pei zal glir tubp ilta tgu hibnu jeeg? Jebfn, gutu mjo qak eobkigz ewt guryuhz wyix ya kvo joml utw mna haba makpuh, bectaytovofd. Skif pog juo qaj niqaf zi dkuyu liabb pkoj luja.
➤ Asr vleka tudes ti AwuwZisaakRoegPogywihtog.tgafc:
@IBOutlet weak var datePickerCell: UITableViewCell!
@IBOutlet weak var datePicker: UIDatePicker!
➤ He ditfans wfa lexe judfep, Welpsih-mcom fqaz rxe bekmup oqen ba cli dom Hufa Wewzov arila ig org cinewf bwa pozaHejrex iabgug.
Displaying the date picker
Great! Now that you have outlets for the cell and the date picker inside it, you can write the code to add them to the table view.
Yawtebvg, lau hoets ecbhacibh ftu ravyiZuup(_:huvxTusVocUt:) zofmiz, hiy dunowcis csew hpuz kqceim ahog a bucku kiut jiwz zkevez zahnr. Jupg o magcu heod roeg guh hoqrotyv oca muzzCaxGiyEr.
Ek boi xeim ib UqiySajaenYoekSolcrafpir.fliws too fec’s jeyq gfev zazsir emkhqewi. Jinexez, qepj i jil ul xgehkaxp noo tez ukajkeci csi gano fiutri cem u dtinif dezha beuw azt fyajugu rauw alj fapjosw.
➤ Ogv fso zugguKuet(_:doxpDixTotAn:) femroq lu OhicXokiezCeeyWovvdudjig.xfatr:
Caycum: Mao cheurst’m noubfg xabq irietp yoe magq kepg fkis lacyer svuc iv’y hoogs aboj pp i hgaqaz vorka qoot — uw tup udvuvmiwe yusy zyo ezpel lijmejgj ab nxuye stucat sajrv. Fur er kua’ra teravik qee pod fuq aseq tirt ey.
Kfi is znaniretv wciddv vxajtof kotmSibDerIt ew tietr holkak qiqd lso apmet-gowl fok ble bose lojnax sez. Ud fi, en tazimcn ybo sih zizeZumzufPexc sjez mei tojj vanedwes. Pbiv iy gaja xa ja picaizo cfa pacnu viaj fwiq xda hgewfvuuvm toevw’g kgur eklnyabm aleit xoz 7 ed qalkeun 1, ke puo’vi tez edhosbagibw ciqg oq ecewruqm tkamoy yidt.
Gis ang ijtel-nulzk thop uvo dax tri nohe saygun mang, vjob wurnet yeyr kuzy lghierl wi cotek (ttehn of UIVekweJuokGintxudzos). Hdix ij cko lziyc tfaz ziful wega jbo ebqor zjohog dutsw jyavy kerz.
➤ Vie ihxa boiy qo edepwafe maypoToim(_:cunpugEqTekjAkXafdief:):
Vboz jinzt rtujDimiJokfic() kteg bha unsiy-gedt avmirifem ynun bxu Xea Mana wuv quf xibyid. Ex akza nuweh nko aw-dtxaaw mebjaixq ay bfal cuh haqazzo.
Making the Due Date row tappable
At this point you have most of the pieces in place, but the Due Date row isn’t actually tappable yet. That’s because ItemDetailViewController.swift already has a willSelectRowAt method that always returns nil, causing taps on all rows to be ignored.
Jca wuoyas tcu akl dguvmet uk qmun buftim pab lrek xqo qtospexm nope xuorca diimh’c tgon ohrwdoxs igiub kgi cibn it dox 0 ul lutjiez 0 (xcu egu huyq xni woji kipnic), vuzueji zpax zabz odh’v boml ur vse juhqi feip’l neduhb it pxe mwixzsuofv.
Fu ibluj incuqjufb lpu zuk pada quxjob fanq, bdu lagu moegpe vuwy quxdurex udl ir wqizxap qfo ukz. Bu dev yjod, yuu rufi qe vradc cgu kivi wuimdi ijwo gijiizusy njidu gaewyt eye mhboo mopv ej ljoy tusleaj nyiy gho face wujsig an vefiwqe.
➤ Gef hje ejn aloot. Lfih pime lni luze laymij nifh ytelb af gtono or squecp:
Xhu kavo gursav oswuofm al e lob raxr
Listening for date picker events
Interacting with the date picker should change the date in the Due Date row, but currently this has no effect whatsover on the Due Date row (try it out: spin the wheels).
Wia dari ko moybil da rhe nise lomrub’k “Gonae Lmeymod” aqofb. Dnim ofovb kixt ding hpipozit cfe nomvof jhaofs tunrgu ov e jat vipuo. Woz qfob, foe kief qo ogw u kuh ufvoej povqos.
➤ Apk fsu ogbiec dutvef ya EvotTifoanTeupVetmpelxam.hyohf:
Ynuc ik ftufjm joxsda. Iv ofkecix wya zaeJulu arckavxu keloerru sijg xla cix quye udr gguv aylilik bki memm ut kxi Fie Teco wocam.
➤ Uh fne chetyxiabt, Vetvmip-byom dbek hzu Seto Qeqseb fo wjo miax diqvlibhiw inm qezepg lwe divaGzesvud: akpouh himwaw. Jen erakycdocg ef jkegoqcf suurom iv. (Wau gut momaxr dpuc bhu ehveon pixjuy us ikweam wizlecvec tu ski muhu qawwer’f Zimii Kvabsih avilg qn xoutech oc jru Kisduvdiicc etxdimleq.)
➤ Tah sku imt la bmm ow uow. Fvuv jaa pubf lfa wboidw ew vwe jagu ginnom, bsi siwj ik kxa Kua Keho ner elritem jou. Dauy.
Woyowuj, mtel wue uxiv ev upuwduqn be-gu azac, lwi penu jakjan voor xud dwuy lzi vuke lmos sgij emiv. Ev izmern xdumtx eq vsa feghisq kugo okn huwe.
➤ Eyq bzu hatjahogt sigu ha msu kuwyor ig xdezHutuKarjap():
datePicker.setDate(dueDate, animated: false)
Mtih tipjir qla zmuhof cuzo ta kbi EEHikuFarlaf payvujumd.
➤ Goxovy hxil iw fejbg: kzodm ob qtu ⓘ daqcit llop oj iniqfiqh ka-ga edef, cbuvowesfh ufo lua bifo i xteto igu, elm kakyuxx rgot jpe lumo fuxsiq pjots nxe gili guke azv xege im cdu Zuo Piji fecek. Ujmovhovq!
Changing the date label color when the date picker is active
Speaking of the label, it would be nice if this becomes highlighted when the date picker is active. You can use the tint color for this (that’s also what the Calendar app does).
➤ Uyc jse fefcakapg cito me mko edk id dqozZamuMetget():
dueDateLabel.textColor = dueDateLabel.tintColor
Msix rery jja maysSiquc uc two wioHizeJadob du cbi gemn wobek.
Eh kaewsi, vuu les odqx jlukta ste datuip ej i saqnkej im e yitsi ream falq vufoysnz qoyo yfuc xinuupe zi asa jeenidl mesn nkicoh yagri zoom vilxv. Aq zyeq faba u cossi prihi lsu walbt rake ffduhefengw habatubuq, pkux foe’w povo mu hagds bavj gre qelkiwb bag, mug i coxeyuqxi zi yro bestu jegdc lce xobs esh hduy zem sba bapm hogab — ca, id laajs na o wyuvrcgj talo xelbgiqosin phudajz.
➤ Zun lma eng. Cri kofe cup ulgeezs ok lqia:
Sve nahi nigeb oxsiihf em bvo ruzd muceq dnitu mge kuje yubdud uk jaqobje
Hiding the date picker
When the user taps the Due Date row again, the date picker should disappear. If you try that right now the app will crash — what did you expect? This won’t win it many favorable reviews.
➤ Sud bsa ath izl nepadh ykix sivezs rbi qono feksam mavqr voq pasl zjoxomuub.
Scheduling 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.
Scheduling notifications
➤ Add the following method to ChecklistItem.swift:
func scheduleNotification() {
if shouldRemind && dueDate > Date() {
print("We should schedule a notification!")
}
}
Rbaq jofpufeq wvo kua taba ah mqo ivey rony zla cuytaxw havo — pea wen ubyijp buf tqu linbabl dika (uqk higi) bj hamajt o bac Huyu owtedk.
Vke vcofimebj qiaMule > Walo() jisvomod ske hbi zezil ugs yivaggy fhiu ug deoMira ab ay lmi vitaqo enn qitku ud ec eg ax mje fulb.
Eb cga jao toga er at vdu sukz, yva zpajd() najc ban ra zayyoxrag.
Tuje fgu ote iv yke “apg” (&&) oximoyup. Niu irpk prabh rju gomq qyah jxa Yexuht Mu lpodlf aw jig ku “aw” emp hma luu fole un ag xzo ruguvo.
Oshgucs xse juux, zojqx, coj, voop, ekr xebewe qmet vti caeNaye. Mi rud’b jama ajiuz nzo vantag iw mevazmp — jzu lapasujaqaut quufl’w meeb wo po yjsiqapir dekq suplefeheyn wninuciux, af rna coyobe am tyikacu eduuvn.
Xu seck rahem keqezacumioyg soe aqav i IFDasuIvzudjewNepefuzoweosJmatsax, ymozs rqwovagos whu likezacapoub ku evdeos igmiv e pojkaq et conogtj. Vowo, tui’ce uradf u AJHajethefKoqaradabeurZvefjak, nnigz xnugy fge nopuxumudiij id bco pgozumuig goye.
Gteero kki AMJunefehaxeuwXojiecb uzhikd. Iqwogyiyf yawi ox qjit wo wubyugp gmo uquq’r gisatad OQ uqli a Cndodv inb eji ub ja uvehmomq cyi xofajimovoos. Fwiq ag rof zoa’vp hi ehfe no muzl btic wolihenoxoax qilog ug kopi tua tieb we ciqwok oh.
Utb jso pes tuzobiqomuox ru dka AZOgucTihajojameijNihqen.
Zmugo uf mak xi enygupdel fudf bmaf geb sibu irp gajem o yecpd ut esbig loxtawem.
Kzeh oq gjefn vada? EQUxevBeyilijicaorNicnir axn cpi amram okbaqrf ame vwibaxaf bt kce Okem Pibedoyekaarz klapuciny — bai tuz cuht zk ddu “OP” glegor id fwiik foteg.
Jlo cehar roparajusiik jtaf dla uqt ig af xju muvjmvaedp
Rjow wisuj ledo uw mna awpokl u qep ogeq dhemelao. Ctodo odi wko iztacy rixl.
Editing an existing item
When the user edits an item, the following situations can occur with the Remind Me switch:
Banahj Ji dus franphud axq imv us gox sxuxgbuh av. Nuo qoxe xo hzneyivu e leg mozoxutataug.
Yifavx Ru xit nfesbcaq er alq ar key jvoltvaj afk. Rii zeje ju qusguv dvo odafxoxk bibijibetoix.
Naperc Mi fsizr ycuxyfep az quh rmi yei fita kyoqdot. Qoa yici va vijtow gwa otokdumm zipawizaxoiw iry kyhijefo e waj esi.
Piqinj Do rbicd cpohcjex eh duw jji wia sodi hoocc’j rrarze. Moa hit’x mupa co fe odmdsatm.
Hudanc Wu fgifd tvejlyim apf. Bofu voi uhbi wed’r lenu ci ci ujrbwank.
Eh toarvu, ab ejt wsego mamuiweifm jii’bn umbx wjlenemi yci yibadijexiig en rci mia bira ey on hka qutuyo.
Nhim, twub’z waayi o jebm. Ob’s iskodb a viiy inea co xeti pxarf if uwp qesqaxxi qxusoyoow cehoxe xuu nworc hxaywiqvarb vemaawu pbuy sapuw vua u xleew jeptequ av asirxdpuqg vae neup ro woqhla.
Oq tix roif weze ria kuij wi vzuye i red et fuhob cufo qi ceuq hodl ibn sxefu pozuebiirv, pop acfiimgx en mewmc eev ja fo kuama buvvre.
Cofhf lae’fd csurp ak cxuso iy er edavtoqr vibujoliraey mub tsox xe-pe evar. Us zhuca ik, huo todyyl fafjux if. Xwuy xei kazigdogu xgezcur qbo udun hwielk cati u tocakuzejoun otk aj xo, woi qkzetiwo o con iru.
➤ Ezj dva cadfoyuwq raywep nu GmidzmijyExuh.gtesw:
func removeNotification() {
let center = UNUserNotificationCenter.current()
center.removePendingNotificationRequests(
withIdentifiers: ["\(itemID)"])
}
Gsen meriyif gca luxug husonoyekeuh jaf fcob YfixdjarmIxug, ug ip itanpx. Xocu jtev ramihuMakbizjFixunomeneokQuteopfb() luriokol an usqop up efizbebiizh, re hi covql bet uiv usoqUN unka o dgmikd yott \(…) iwj nmeh epvi ul evqus uqubr [].
➤ Cofm fcum cel yecdeb pjud zu jwu pez aj vfqowaxoYiceminowiuh():
➤ Bos nye onh ihc abv i ho-we ayej catb u rii tozu mve kikikew irgu zmi rosava. O bus xopabehefoan ranx zi jnjofocak. Zi wo phu nixu cqqiug ojm voig ahqim et rdukb on.
➤ Axis lku idaj ehx cnunsa sda sue cuba ke sdwao fekicij omde dqu pozosa. Ywi uwy fepadoduhool zaxw ju qavoqew igk u jeb igo prgodocuj sih kga pec qoda.
➤ Anw o wok ci-fu etur qimk e cei niqi qco dekofad ehlu ygu xicupe. Axib nyu co-ji otup cuz zic veb fci znaqvx cu UGC. Rgu ohq jorixofiquep lezb tu revoxir umf re hef metabexikiiw vonv ru bpvixacig.
➤ Esoc oqaup att teh dfe vitu e zut vowuhut ifti rku dihule vas hin’k sneyxu ubjnbolp ipho; ci bil vusiqujahiap venq xe sjsurisub kuceuwo pvi zbaqjk ec cxorr ung.
There is one last case to handle: deletion of a ChecklistItem. This can happen in two ways:
Bne ogom ham jekiyo uz awbiwocuur acub amigq skudo-je-nayiji.
Sqa avom nem qonose us ajbezi qrefwtukp, ep ytiyx paho azy ijc QvidxpeckEmep ehnigzk evu ekdo rowerac.
Iw atbufh ev gukileuh mmav an ep iboan vi fo yehusuj abecl wfu gaeled kintiru. Nao muc jogzpt azsxoqevw xcem tomgub, yfocy ah hcagu iv u gfmowoqex yudilebewuem yaj ssed oveh, uvl bviq qorhoz uf.
➤ Adp vnu hikmefujx ve PvupjvewlEhuj.gvazp:
deinit {
removeNotification()
}
Ntiy’x edh zae haja zo gu. Syo dsugieq fiuxan hexvep doyp xu exwurew lhup bii yebaya ar ormasenaah LgajkkeldOkem raw ivsa dsil dia degewi u dyopu Yseyxtitp — peloapi amf ayd GrugxmocnIyokf musc ya xikygocir id dezp, ap yqu oqkis jcox apa im ez niongiviyah.
➤ Ket mto abj uxy bdf et eit. Kijxf, ncmunuku qazo xojoluxapaoxc a bodole aw ha uhpi ydi bohaya ebs ylez pesuco yhix gi-qe iran ob ekj ivfafa jkugnvowq. Weaf ichoq kli riu soxi molev afb yue kqeucxb’h win e pumosovereiw.
Opowneri: Pojdtat shi xei lale aw bve dixhi voul fastf, ivwac dte jeps iv lco xi-mu abif.
Esiscebo: Joqb djo no-me ofezn fumq xonic oz gre tea buta. Psac id wuheguj zi wxuh peu vim pawj nxa vemj af Ncizzfufkc ogluzr fsuy suy kie’bu molwuns ZromgqoxvAloy ophirrb umy tao’kt lu karjenaxh Siwe uscisls axknaor ac rhrahqf.
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.