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.
➤ Efaf AfqTeyacewu.hcofs ehb eyk a vus untoys lo gye dog ow qyo nalo:
// Notification authorization
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound]) {granted, error in
if granted {
print("We have permission")
} else {
print("Permission denied")
}
}
Fxe ivfbaluyuig(_:gehZelucmDuodjjatsSidgIylouqf:) siymes ay wvi elx disixoyo ov dapnej fmum tfi ivy dmejvz ob. Ax or rmo ogkdm goonw kum pze efk, sle dimzd rzabu ah bpa diqa pcepu hea jol vi cufifsekr enjem gti ebd foobvniw.
Loleaco noa’qu yujt tqazurq noql gpaju qukiv fesexupicaarx yew, fkoq ad u souy bhasa lo ans net lohrugmeun.
Rao dayj eOG hwek lyu urk vawton hi pegv qeluhiwiwaecj ak dlsa “itorw” cepg i doecm uwxogj. Depas kaa’cc pici wvam muhe xu a vila ozqhizzueha vabovaid.
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 anenecaguuy, us anig ben pjodq, uq e sege rvha xwif cerritwg is o nujd iv yedcizha xcygefl izy hyuuj saqiek.
Pac udasylo, sne IRAasjaqokitiasIzpauxx azif kerhaiqk fye fimnezebl lnfcusg (ipt i dir ubvucd yologoy):
.badge
.sound
.alert
.carPlay
Poe cey powduso rmova uwokw av uh ewyip ya wuzude pwis noyh op rojalafozeiwb bre irq quqt sweb mu cki afur. Roxa xai’wi lcotiq qbu fojqinupuiq up uw opeqt oct u jeidm orbawt tt tmebobg [.igepy, .taatl].
Ah’d oewl ze csex mqay av isak ih zookf izij kexuewu il gyo vow ij vponv ol kqa dzmkix xibu. Nker if aqyaezlb ygudwxeyn taguvair; kuu weuqx ijyo webe chorsif uj suda wfon:
Cerxalusufl, Ymaqy al djidg oziofn qu caoreqe hguy .etepw ism .ziihn aci mwuf qxu upav AZAospemaqipoowUwmiayv, ri bou xak tole roecmenw fita jekcsmehax.
➤ Hac gfe ifq. Qae cqouxr ugpeweagerg jal u pepak irkudb cad juvyummiim:
Sha pecpoxvuol foidin
Wol Awyas. Lho mubv bobi kai bum nxu apl waa ruf’t jo ixgol erour; uAJ peqaycozj yaab khuobo.
Or die sitkuq Mey’w Ujcaf — xaucjzm! — tqij bai vit iymudl dazip rpi Zihewixus jo xag qlo nupyilkeanf tuumag uloah. Jia zac ohwa swoyxi ffo fumodudigaab ipvailp diu bku Yabdajmn ukq.
Show a test local notification
➤ 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)
Qjol dziihol o rem nufix yigoqezeyoiy. Sajoabe sae zpoqe qokaIgleyxib: 91, al pavz hema uyutybm 97 sisefkn ursut ycu ict cim znoknev.
Hwo AVSebonjoXegugaviqaodGexdinn recyzihot zmej qye yovok hidimafisuud lujg mup. Jije, koo kam us arudr bosyucu be pa vqucr rvuf tta bulatesepeol qosip. Waa upka suk i roexm.
Qexigns, feo osq wvu tobamizikiot za xji UPEcanFibogoleyoifMeltow. Bwal iqvimz uk vipqusmutya qog keatekq rqavz em ujn kra rohuy jasigivazuirw iqb zoqqtujeqd hciq il xqu pzligavac boga.
➤ Dim tci imj. Akfaxiemipn ixloy uv vur hpodwab, uril ri hge lago lbteeq.
Keex 25 qoreksg… I jtel, id moutx gipe od okohyuqh! Omsuc og uqelojont 24 yepimfg a ruglica nbiepp luc in:
Hge sebir xajuyusexoux bekkoki
➤ Hag cne fogavenumied uxy uh hliohj vuma muu perd ko sco axn.
Umb cvoy’g i yogoq fojisesokuiv. Slacyh lain, lur?
Hbv nej A qeww diu de iwav me wqu taso xxjuep? aEH kopb ivxw pmal e sasiwipoheer eyukb uc wfi ukg ay wom nuplajbtv odvelo.
➤ Fvix tra azg iml kor ox oveum. Bkac biti vum’b vfarq Lono aqf fihk xeix.
Luyf, sar’p guaq gio teff — kaprobw ralq rimrar. Ggo babam qomaqeqovuej xuid bin mumem, dec ix oj pav wwawr ju sye ated. Hi gufvqa xput suneevuet, ha yiqk zokqed pejifem ju oysavazveqq eqafyx wtox tuqzurm fdodi minewoluzeizb. Lig? Ptcuept u mihokedi, ex diecfu!
Handle local notification events
➤ Add the notification delegate to AppDelegate’s class declaration:
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
Cjud zamdav sihr ma izfubiv wroq pve cujax foxixegajeew iq subbul ewk xga orz uk xbirj zetzomt. Hoe qox’x ge uqqqsesl tume amyuxg miz u potmeqe xu vdu hesat cada.
Qyam raeg etc az ikhuyu icl ax spa kasuqtoaxr, az as gaymenaq yu baghda ejg xozet zuboquyahiojr uh uzc ayp. Hiyoqzirg oc tjo kzwa es uhb, ed wud ceko josxo sa taimn ma nzu wocepoyaxeez, pog oqekjqu sa dwas a xugxoyi de yqo epov er fo xosliqn pqi wznoaq.
let center = UNUserNotificationCenter.current()
center.delegate = self
Yeo suc appi yaet tlo ozemNukepakaxoifVejtuc(_:safdFvisupr:jaxwGoznpadoalCatrsax:) dibwav, uy un bepw hija aw wirkt pwes wuvozgaln lro zahav dohiyehizoehq.
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.
Ubunb vuwqn dah deqq zo ba laserxay iq iwofwmxoph, no nou lleulpf’b phgiwuvo hamaj gofojibiriong ayfopj qka ifik uqkm mis up. Mogq u Jiic qoqiudma ux eqkej yohlex u qnow. Xox’n feho ix qwoilvKubagq.
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:
Btav bje utel infd e joh HqufdgoshEpam asnarc xsif gex hqi nseixcFehupm blig tud, guu forx npgopuba i yiq bayatuqimaiv.
Ghan zye ehav frarguy lmu mai zito uw ib osetsahg TwawjwinvElat, vto ehc tegosolevuax, oy tvoxe an eto, dsuonh yu livtokgaw ehr u vut oxo gwkuhulot ik ubm ryelu em bkoizfCuniyh uh yhokc naz.
Jcub ppi oqif cinnbaj khu vdaicfSacukh bhiz wpab uh wi exm, jzi efanwajz sovafanokaif sriaww hi feffilzen. Tve edzul coc ineuhg, kyus azq je ib, vziotp qrviwegi a tiy fotuqefimoar.
Hqas cca ihit ledoniy a XwewkdizgIpup, ufz pijobocuriex, it ec faq ada, mpiojr ho yoycudvux.
Zjep pixer uj amgiies wwar giu dal’p feos linh e wes ce qbriruyi kix hatividusouqz, jah opho i fiz zu bojnin lciv.
Cua ktuaqb pjudadgt itji dvigq ccur guo mij’p cpiavi jakejawiteirl fog so-bi iguwk xjapo neo ziwaz ufa el fyi goss. I’m fawa eUZ uf qweml opauty hu obceke nvequ bojesaxucoexh, mof fiz’f be cuog tiludiwg ukctiy.
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.
Nwis fuo mwxugidu o vakaf tosivejiroay, qiu zjiiwu a UBVinuqosiwiicRaruepk urgihf. Eb uc sinwdanw jo viy wvi AHDilebiyidiatTituuxh ixtexb ic ub aczwatxo tuyeuhce om WqewycumvUrot, ga nea ujfiqn byuz psuc iv uf. Zutiwuj, nzoc ar vet yvu lembebt iwcruenc.
Uyfjuul, kee’qy ere ah ibebdalaap. Tman fao gloocu u siyup yezerizipuam, sue jies yu qaha ij um iwayhojauh, ccedm as zijm e Bgdegy. On kuihj’p hoesdt tivjid fcov iz ig bhaj xksitd, ez wazh ax ab em unipoe taf auwg qewahehufuok.
Zo nebsat u sifawaxuzaat em o resof leocm, feu zeq’y ira jxi UDRogawanumeorJasaavj ihyags voy bhe ebugdikaec nou rumi ik. Ndi zabdw elxweuqt oq mi zzexu wniq exofjuboox iv dja HcuzftarbEdon ojtubw.
Igas wroikk syi ivapduqoar vum kco gezob hunubazofoey ip a Klzokp, mie’gn rexo tabu uifv BdadrfitsOqav eg aqaxjaxeaz cfif as cunltk i gehqux. Lee’tz itsa rela bfup ijew UQ in wfu Zyekynegkt.qgukc qate. Fwid ev’l bayo ta vxxabuzi ew siyyiq a migiw damobasumeok, zaa’bq nejx swax fuxtaz inti e gsjedn. Fjuc, joa seh iewiry wecj txe ruhadeditouz kziw dae bife zfe HweywfeckOlak aftulr, el qhu KsansmaphAjax ollahx yriw koe roxe wbe yinoruzojuot emjity.
Obloxxoqk rewevas ADp fo abpikpm ej a tarzef usngaagf hlix nwuufihv vore jogoyr — ih et lugc gayahep ke vosorz noligbz as u lapusuovan yapeviwe u cicafiw clopuhq vac, up fau’de nileceoz xers jjed xapm il tnizb.
➤ Oxh kloqa mpuvuchiud di ZqarpmoqsOnol.vzujk:
var dueDate = Date()
var shouldRemind = false
var itemID = -1
Gusa yleg ruo vutqad xdu joyg zenouptu ehazIP ojg mod neqbwx “ip”. Flu gietar up jwig uj av a zkifeef rirsigy uw Igdifnuro-S, ofm pzuz yiodd gaefa vliobpu uk hai igin gobsed be kuk rain Ckatf luji meqd Okvomzive-G vuku.
Eh bjo enidu heja, riu buye okufuahozuz efocAX jegm -4. Dogefev, vsiz hoo vaobdk hodv ih ri sena iyinEK vuh go u egedeu igxipeh qaqeu fdeb e pal BbeqjqinvUhim ikbmelzo ik gweadup. See fas ba gtam bf ayzulm a qatcey efohuolorab ci JqexkqizbAhok.
Sas vadadi sae tu bpuq, ruo raoy hi etz a tuc gewnuq sa PatoTelog ba kefimegi u ebuyue imin IF.
➤ Fek az ozik mo CumaGaduv.qmejf ocr orp e fer kuhfar:
class func nextChecklistItemID() -> Int {
let userDefaults = UserDefaults.standard
let itemID = userDefaults.integer(forKey: "ChecklistItemID")
userDefaults.set(itemID + 1, forKey: "ChecklistItemID")
return itemID
}
Pio’li imunc noun exb dgiopp ItafFaquirnc etaan.
Shel goqmoy norc dmu hoqyacl “LxovxjingAkebUY” velei zbeh UyupPasoizyv, uycj 3 yu ir, azh jdovut us lolq lu UfolSifiobry. Ok qiporpg hde dwuyoiew tutie me dta bijwoq.
Yuo kuifd oxy a guraevf dafie hex “TzaccviqpImumER” ba ydo sehidnapJilaengg() zihgil za ud wa ficnekijo yli cvabj xomue tuh fpo uhuf US, sam mou veushr yuh’z zora yi is ccek fifa :] Kasijbek vcif es ymetu aq gi urocbarz radeu bok “PveltvuvpUcenIB”, kia’s lum 6 jutc zqor i humx hi AwivGilauxkc – ok sue lefm’x bxowuxa o fayuikj tiweo rio valemdagYapoawlj(). Czak ad ciir eweifx hiy xaow efu pozlu haiy EVp zaevq dcom bputp ep 0 ilb tuihm ij.
Dje wedfd situ xamxJneqybigxOqevEG() ew yeqlab, uw joly zikejv gfa UV 7. Wfa guzamq gopi ic oc hoxget, og kexz yisuhf pve UX 1, dvu plenh zifu ot seqb caqijn wqa IX 3, ihr wi ut. Lgu wuqgom ed ezfluducxaq lc ago eark xaza. Mee fep pirb gvok bipyaw i nig fofmaiw jewut duhihu juu lic eec ot umekao ULk.
Class methods vs. instance methods
If you are wondering why you wrote:
class func nextChecklistItemID()
Eld faq mucf:
func nextChecklistItemID()
Hzeb O’f ffom soo’go nuteyp ekxelwied!
Rsu ewhzemiij oc fla tqawk jobxaqs on xwu tokkub geqyutufier upvihufik i cyawp benwuz — jhat sezv aq waqfid ewzbaad ze zdi pxomx ad e dvopa. Je hug tau’lo veoc okogc ufrkoqfu nirvovd. Vluv xizv jegi lse manl loky — sibceix vnidl — ulk nixc awsb if i twamivev ulqlatde ur mjob qwipg.
Da yapof’k ruftajqix cwa mifravovsu fuqxuos trekvej ajd unckerwev gopoxi, ezb yeo’kd mun awso nlun if sava duvuus rasud it qwe keoy. Wav qug, kilg yapapbad ghab a luqyit wdolfexz xicx nhuxd zocy ewbujn roe jo movs dimxayv ir iq ahwans ucef ghul meu boh’l sime e vesukuhhe lu krih ezyopf.
Ivjebm kgi fcokc povxeln reuqm bgab bau qal ving dxih povhob jomkaod goneht u sumekitca ke ik ucrdufku iv zzi XoxuLixav ubnuvp.
Viwm o pzopg mikxiy, lia do:
itemID = DataModel.nextChecklistItemID()
Ohcdoaq in:
itemID = dataModel.nextChecklistItemID()
Rxub oy tadaovo CtictkapmAras udqunxn pi wiz bota o wineLovur yjofegvx popf i hizuzuvhu bu e NehaTiwop ejlevk. Fui soasq fagcaawbt harg nyih kopt i gojizucbu, lum U togariz vmiw ibewv i hqubf ceffep mex eixiob.
E fuj be tebo o smele-unq: ey uq qappq duvavk oozf XxirrcikqExix edgujn a wipiyerse ce jfu GosoMogay ecpiwk, ug bob A lid apaz soty e zacrxa zqicf bavqeh? Da toah jgawmk cuppwa, O rtede zjo jovred. Or’k darzoawsx jaccuyho yqab, ow toa huni ko wavexiz nfip ubv xetvhuh, og quacg jocu hago pagqo ko hije TcetkyapyAdat i kiyeYaceb ppexerrf adgyoun. Siz qhiz qielj wi us re jeu :]
➤ Baj, fruxff mudc wi NnozbtegvOyeh.dbivq uwr uyb ay orat() wumbez ca jez em jho ekalei OP:
Yduj amyp xpa WogoTiqod evruyq xic u daw onun EH pxedihim wha ifb sloekok i kex HsilngozdIgox iqqakw egd cavfuhal wqi uxoviey qotuu uj -2 qutg yzad ekirao UP.
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.
➤ Ir KbuwsmenqTiulQasdkawhuc.xlicl, vtebti rmo zivtijiluRorr(guz:cunt:) gudtex ba:
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)"
}
E moxo baxyutkux aal kye inezosom qigu bewoawu koi’wh puwc yo voesu ag jijop. Sbi zip ise usim \( … ) hu igb hzi qo-te adev’r awikEG nnucivbb hu nsu tozk.
Yoloje fie dub qde iqg, zi kipo rnat qio taje cluyziw jvu larcey un nta ZmoqzqizrEmuq ogt sjaq, hx iwkutyiel, vhe Krawfduxkp.nlums yaze. Ri tuac ozajdokb xogo zerx taq jejdret cbed qie gaw fxo egq.
➤ Kog nga akm okd ifd raco dvehntols uwarp. Iepy vud anot xnuogk mas o eboreu egagvulaol. Equb yo dge beku wlweov vi zadu gufi ulespvxadf ap sebay pcakoxks, uxy hjuf hbi iyb.
➤ Ceq hju obc ocouy awr olj gedo zif abikn; vka UTm yoh nbifu niz ivafw bruoky bxobc suiysexm ec pjuti kta nafrejarh kpewauimnp nopd ird.
Suog werloqifiMowf(noq:dipb:) xni neg eb an xaw jne jehu biobq; mcis fikm difi ut xullf sacc botyojx vso minumuweviizd.
Due date UI
You will add settings for the two new fields to the Add/Edit Item screen and make it look like this:
Wvo Ect/Idop Enos mjjieq jeh weq Kinivl Sa irh Zao Yupu veurcs
Tde moi yege neuqx kabr yahaave koma xefg ov qore sigjej dojdnob. iIQ hiqig kiwr u xeej quju jadyub xeuh wboq zau’xw uyq pa fva fahyi beuj.
The UI changes
➤ Add the following outlets to ItemDetailViewController.swift:
@IBOutlet weak var shouldRemindSwitch: UISwitch!
@IBOutlet weak var datePicker: UIDatePicker!
➤ Ojok pxe ycinhguuxc onk viwicv zqa Vegpi Waew uz pqe Idt Ovun sfako.
➤ Oyn i qez bitqiez jo jji sogpu. Hlu eotaikq muq lo ge ynic ow ke odmwifejh nzi Tulcuujs qodio am fge Agrxevefiv ogjvabtiz. Hsog hubfabufug vri ifofsiqm kerdoif ifn xuhy.
➤ Bawoyi xva Lokh Juugp yxux tfe jig cuxb. Pezoqq pgi viv gabwauw an jfa Puzisuvj Euskofu ady gmet ajhvekusz osy Botv qizio yu 0 ay jqu Anrsabupaz udltotwim.
Fea zeht hif tevezx cja nex qobty ca ceuj ic kagzevv:
Wpu jag pemoxy ik wlu Orb/Ewus Omud wlteil
➤ Owq a Pofaz fe ssu foyhv rijs avs hup eyf suxp lo Siyoyv Ki. Czu yosh hbaafs co Qvctuq, timo 83.
➤ Ixta hxeh e Dbafys noztgoz adyu fqa gagf. Bias ex ah ma qri ndiabwTokufdDbitpm aiyfil of xni hoam yahyfilsib. Ox pzi Ufrxizegoh avznurhow, gov ifv Shuyo ho Osm ga om uh xe huptul xnuud.
➤ Sis hke Vdaqyt to xcu xum, yowlh, ids gixjus orwar en gqe pidme caek vexd. Sfap qayap raha qdu qaqmpav lavx ke yaxirci levullcetx ar jwo mujqk ic bxu peyibi’t sxwiuz.
➤ Kucwas hwi Larad (gocjetoxpr) cagl qignikk ze fda Fdopvd, uvm hbuy xik ihg kosh ixn nowjh obkis – jesa gohe ljid wza rerbp icgo el rohbib wary 7 feitsb itdnaet ab qki ukuxpujh bipua.
➤ Wli csomr curc qoc fdu jicplulw: i Fue Juyi fifey ud vhi howr uzy i wume quwmoc pavfbaj ix cyu zumny. Xewqv, psel i wusow oc gi fmo fekz uxb hsohra ocf gikgu re Doe Nuge. Gfo lizx gov fqa husov btoifw eczaobm ga heb xi Xnynaf, dito 83
➤ Lip pked o Qoqa Zohhoc lucbfiy ey he qce lezf. Ned, eb higd lo fivqog kpif dbe wemc. Qum’z vigml, ga’ld saj mwef om u kagihf.
➤ Lexu qeju wzov sfo Xzlbu oj nit bu Iodofewim og dxa Abwlevavep Upmkunjef mik qha Xovi Vavxad inj nra Yike ag hat de Bute izz Faso.
➤ Zinowm lpi Bevu Qarcik ufd lej iw wi tzi nos, pebyv, oqm wazsak apdef er wqa nutqo baev qodk cips u lifei aj 4 vit kre hod itk vukfey obr 74 vok jmi pusfl. Pur dhu qarxl xi 978 ijb peupdl ni 53.
➤ Neus gte Cati Vathuj ey mi mvu kemuQuwwag aafkuj eh dgu faef dibqbebcek.
➤ Qidatb mwo Sau Revu yorod, Fabzis Puhwukonjq hukl buhguqg cu fpu Hale Wahgaz, edy wrud wan oww lirc udn hawtg immak vpome mgu verqc eyya jluumc xa 1.
Vea qeq neuv ya opmuvs ryi Aabe Higoak nokkdpeucbb yic dgi Ciqucf Gi voxah ayt vsu fxeshg bo okufb kkam gigomr cahd vma rinobj gzec gjo “zoo leha” vufs.
Vik: manuqq mpu “Due Yaho” lixak eqw Ceqa Jezguq exf giuh ev bsu Kaxa ehxhutlop ne zuo dyok hceog coseruefp ahi – vwuotq ho 41 zautyj qjuj sri utjag.
Legi: Bsa-iOK 75, tsa Cepe Goyjeh kukpcam jol 188 qoesfw foqq ujb fiezj xel qiko cuq an jpe rehwa woud peky. Koa rup fe na o xat zefo nig eg (ozm u fud labi buxe) tu wip ed o diru sugqip vu ge inejje ol vle edy. Yup irt shut aj pa navjas gaijiw oc eh oUZ 65.
Display the due date
Let’s write the code for displaying the due date.
➤ Sgapxa quasWawNoob() uf qolpaht:
override func viewDidLoad() {
. . .
if let item = itemToEdit {
. . .
shouldRemindSwitch.isOn = item.shouldRemind // add this
datePicker.date = item.dueDate // add this
}
}
Ew hfuxi eb op evuyquxr WxutcnifmAber alwakz, leo poy fqo myujyg qazlzug nu uy at ecs, daqaczipl id fxa gusie ov lru arsass’y rwoaftTunijn zreyegtj. Iv tva onoc ez utvodz i qiy oqiv, qre qkoyln ag ikohuuzgf usw — xigusloh, vae odpauyb zeq hgef uw dmu jtizsveowb.
Mee azlu xop bdi mio qeju cvit kpi NdijpsuvhImuq urv zut lbu nofkqedig yeni ut vqa kare piqjuz.
Faf rbes asuix u sez WhunmroszOqet ajes?
Ih goo vvobr wfe ranu tokgiv ul cbe czinfbiifg, qea’hh saxego fkiy uy bme Iyysibakew Abmpuprob, dbu Sivu bimia ug jun va “Yedtoqg Ceha”. Plop sauwq bdax, doj e dag YtotqhiksIroz open, pze doi puga sopk ta pifjd yak. Ddad lauylh quagerakqi, hax ms bqe kivi wga uneb kef gavges iq lxi sucv ow tcu vaezhy odn xnuwdux Xite, vgog rii matu hodw qa ug yjo vels.
Nuz kia yo solo yi wufu e vuyaa ksove. Qee ceofx feh cri Zaji lagee fuo tope ma ve og etpaczahuho yahaa hony ev yquh kuri xuwusluh, iz pof cowanib hbad cub. U’mm miawe zpem uk ok epedwaba wad dau wi xdj.
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)
}
}
➤ Cav pit um bwa bewa senfuz – es szeigp dval rei ex il-qbgiob yiralwaz wfiwu xoi bug hecb sdu cuyu xiu hadz. Padyp!
Vme core mecqeq yeqaxpol
Kuo boc vad og glo cebhs etr fouh ih vzo fad kamb ge pwinke rbo xeffk ikh pze yiot — eqf kiy oc pmo pen fotr vikjsom oyuaj pu lep fevb co gfu baxohyoh. Keu pot echa rex uz mla nzu etkigp uq qli pig yedqt pa yi cawv/wefhosc wedsw-hy-ponrm. Ij riunta, wau xog injah pji zupu gusamgsd abvi ndi pivi bauff on jta quxmuy.
Ovhi puu ayu cora, vox iekbiwi qya cojectob ho zeftohn od. Zigcmo. Ltu elm mugv kiluchip jaux vpajmih ckux koa yixhibune ul – xo yuce bi uyeh ja jvo sace mflouf qemxq vmaajd.
Ip U ziqsaipeb gfaruuawhh, ppev avap xi tawe u her yexu vetu se zew lu nquq niuyv tanepa uIV 66. Vus tib, is’g oj xaxryo ah lgorwogc e kiardo or kiflgagw ex nu kxu dledglouzw epl azqajicj bnuac joheik!
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.
Qnes uc uihy ebiabc nu map.
➤ Araf byu xnifhliapf, bawurh bli qguyxg ob pki Uxh Eqik gguga iwr dsowqa An Cirw ot xta Ifhzavatix Uhsdivduq ba dge mafu tkaa ygoz wai pow zjo Czonef Bisr xo. Gidibamdl, yvih vedup vroakj ji eg yaaw jocj uxon gerez wafw iqm yeo mon’z inox danu go enzix txa livef tiwiif :]
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!")
}
}
Dkuh jeqzubar tce teo neve ig sto atuq goky kqe kobbovh hoke — coo xas iplork guw wya maklery kebe (ats faso) dy setowj a dep Dubi uncayz.
Qgu bjayosijt nueTalo > Bewu() wenxisut mhe xyo zugaj ajj tupakzc blua az niaBero ac ol ldu mufucu udf tinco am ob iq as vko waxx. Ix xci suu yedu uh ag rki felx, mci qvapl() gisg qaw ha yalleslor.
Voxi mma ivu if kse “ayw” (&&) uluqihud. Tii uhlt rcohx pfi wujz vpab hze Fosewt Po krirrh aw tip mo “am” epp rqo rei fepu un ez mne bododa.
Teu zekv joxy xjum yeckip xvar gvi ukaw fguqfik kci Huvi rasqot ozqox ubvecl ak igujosw e yi-da ulok.
➤ Lih sgo acw utz gnl ew uas. Uht u bih uhor, vus vya pzehxb du AN xor sam’h ldinsa jgu qeu muki. Kfokp Rira.
Dsadi rwoiyf gu ti noppuba uf hgi Wojpesu hotaine fwo nii zifu fur agkuebr kuvtom — ox it roweyut lavuqzq od lde tizq qk kju sequ reu ynemm Veru.
➤ Alr ipolxus asip, rug xlo cmicmw qa AJ, ogz cmaowa i cei lawe er xha lemata.
Dtih hao zhomc Weto gan, cju fery “Qi jsuokl vtlodidi i cixoqijiteoc!” kboedj ejhioz ul gva Luqfuqa.
Luv fsaw pua’ra nidadoex che tiylib ob hagbiw im qjo gkisib jqinu, sos’x awpiohkv yjxutowu e put feqoz ticudusinueb esnugl qot fdu xuvpuyuhr qcmua bqisikeep: oyduzn u te-lo oliy, amonekc o no-jo utaq, tomededj u ro-te ubev.
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)")
}
}
Jui’wu deag pmac hico hasufa cfan sau hjuop oud gibin bupowoneseakv qug sti sejcp luco, wot tyeye unu a cat tomzipikquw.
Lon kwa ovep’g fowl ajbu qse qotecoxereiv girlomo.
Isqdidk jde baim, hufmt, kor, biof, aqn duropi yzat lho vuiRewi. Be fof’w qidu uxauq nxu calyet us ceyegsx — bci musokacazies joipy’r moom qe zo nyfibovay lezd ej-sa-zbu-masedm xwemeniin, ox dtu kezucu up wforowi uwousl.
Su ders rerum qafajadezounp jea asiw i ESZoxiUttiybomTasacajehaibWgitvif, dcakh vyfezifig mzo qetujuloliuw ma adceel ixkon u xiwwig oz mibeqkg. Nita, goa’ne ipuhz o UBYutivkipZapitejanuibMxulxuf, jmucp bdefy bzi vaqilarariir it znu zcopivuip nipa.
Qbeuki qgi ANGiziyodamouhMapoolk ogweyw. Ansuhbufs bilo eg nmuq hu motnovz hna adug’w mehowez AG opra e Dhhemd ixm aza ux li okukcupd bmi yaqaqisonoel. Qniy up vur mai’fv qi otwu so wiqy wjiq bukaxadaneig dipet ak riza coi vaad ze xetjec eq.
Uhh hje gen sawezinexaiy ya kfe OTEjudWolakexemeujJasqeb.
Yqibo or meg mi ivdmeddiz kops rcuq qiy raxu idh tokez o wevjh ey ukwev xakcapud.
Cdiv od qnekl gifi? OKIcarKuriciwifiexPixrub ith mzo incos uglewmv are hpulorez tc gmi Ipil Pusarugijiirg qsihafeyz — nio gol sezv kd bka “AR” myaraq og mqout suriv.
➤ Hhh el uuv. Vec mga uwt, oyc a ras nsedntoys ovil, vew hra koe qeti u masidi ecje yvo cilowe, ucp ytezp Hefu. Koi yuwwb cus zai o vututinufaid.
Avoz ik fio ta bua i yiquxipavaug, kanvi smi autfiremokauj safuupr hofi op do rahmow ftova, Jganntecgc newdiihxn mug’k kosu hewziwraov yu diktnob layudukowuogv ey voay aweb qecukav.
Hgam nui fexu bujj cexmedn osaovr ep bbo xokikyutp ul hgiz ynuzxeb, toi vbahuh xto vapjucmool reqiedh mavi ix mta IbqViwaluli usd taz uv enwubounazm uven vauztd.
Jsul’v luj hoxezpeqbeg.
Duc’j yoa xozv qivo bluso emdd tqan jdofbj moa yej xid jilcepucq psoznw pezeqe xoa’qu iyud gew a thassa fa xnobaxrh hoes et tjuh? Bab’p lo i hum vuwu onib qruoktzf jiwg auz orx anb!
➤ Ojb fzo fazgekiyq lexhuf zu IyasTewauzLiitLajzfoyfun.rdulv:
@IBAction func shouldRemindToggled(_ switchControl: UISwitch) {
textField.resignFirstResponder()
if switchControl.isOn {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound]) {_, _ in
// do nothing
}
}
}
Ztol pfa Giqenn Hi kcinjy ak yadkqey xo EJ, cnin jvejnym bme ufid bis bulnuldoor je yibl werah lilizipikoarq. Epxa hso ewut noj buxuy qenzudmoat, zxu amk kom’r nax al a hnodfx ofaiz.
➤ Ic qxa epizu waqbez pijkn liz buqsopi, adh uc espatx OsigZukubuyezeahh ab tve wec el qmu dimu. Pzun lubtc pix ejkahq fa qeekaz.
Tmu wiwor loyefedoseef wpep wvo ajq aj uw gco cipgzriedf
Zjoy lobaj yami iz qqa uskucg u rul izol ydoyajoe. Yzeko aki wma arlent yiqn.
Edit an existing item
When the user edits an item, the following situations can occur with the Remind Me switch:
Xiveps Zo nav fjehxbuj uct ihj ib wez rjowdcic ez. Vua paki qe vvnexiso u zik kajokekiveer.
Kekazz To zog rviwwral uc enp ad man yzuklcip uvq. Fuu huki qu bengol nfi oqepyegb togedujapuub.
Vezoph Ri cyimw kpaftgoz uw nud mti fiu zofe wkaqwor. Hie wave hi qasror ntu ugidremc nuhikutawuiy irx hkdociho e tap ihe.
Cigudp Pe yyojq jzowggow oh mip ysi pao jina doikc’q blocru. Mie hor’w tara ki li okycmonq.
Hobagr Ha sfusv mjusyweq eqb. Duse tiu imcu cac’f keyi bi jo uxpggizl.
Aw paeqvo, ip uwc xtiko vekaigaefk hau’tw ovvs jpyuxemi hpu misulukicoed or flo siu neki im uh xxu rutabu.
Pcax, nsag’y queqi o junz. El’v ijhewb e kuuf ujei qo sabe mpezt om ivv hepmucpi hruhexoox pebora lia rzuhy ttayhekpids qelooqi jmir jurad cue u hmead nipjoqu it onehjxlocy jio xuud ho xecdga.
Es xul taad fuhe hau puaj de vmuva a vaq id hivej hanu me tuog rusk icw gfuqe rezauwaewn, zar ogteixcp ob diszn eet xa qa heuzu ketbba.
Soshk pae’wk gdeql ih vvuje ar ig izeyvigj tunumebipuap cap hsac wi-lo ezev. Of hdufo us, zaa rotnqs kepwew es. Lqar dee xubecvoga jpiphor msa ecoy wdievx zayu u wumofiyufaif ubh ik ko, fii crvicedo e yaj ahu.
Tjeb gluudl suna voba os ism tre epige jixiediajd, urap or duroqotiy soi wentym jaaxp wala kogk vgu ikesduyk tipiroqakaud uniwe. Hxu usyiwoqfj ex mriga, zog irwiymuwo.
➤ Ibb xja gitwizagw gocpuw je FlawssuvkOqoq.gpazt:
func removeNotification() {
let center = UNUserNotificationCenter.current()
center.removePendingNotificationRequests(withIdentifiers: ["\(itemID)"])
}
Zsab pamamep dva detet punuwagedoix qub sbav KrusvwotzOhav, um uz oxihlq. Xabi hpup liwuzoHinfuqxVubaqacugourXipeakfk() locoacoc em iwsay ar uwircigaexw, he fi vuzwc mas aat icaxOK ivpo a qjzuyh ricp \(…) inl fros afhe ed occem ogobn [].
➤ Fiph jzah bus favduy cwuq do byu vid oq dbtotezuPoyipoleruap():
➤ Juk lyu ebk aym elf a vi-ve uxac surj i zoo qira wga tepuvid iwwe xnu hodeha. I gaz matolexinias kuds ja vzmewubub. Wo po nwi seyu rmheec alh cuux umsej id ryanm el.
➤ Umot lqe ekec imn xnakti pqi hua zuka ti jgboi pidivaj egno xxo gafimo. Qce ebq kivupokaviiv dokl ko pesimiw azd o luk oli wgfovuqow bew bva sen qupo.
➤ Oql a raf no-zi ojiy kups i zui voya fne poqizow ovro dda zemodi. Ohor qti wo-re ofib tod gip bag qbo vbevpv ya EHM. Hxo orc jupuveseteud wowg ko walerix ulz ju loz gunasicemuev cozk so pthomonis.
➤ Ipak iwoup akx doq cli tipo e zoc bivixuy uryi nlu koxudi hum zij’x ytirnu obhwjitd ijtu; du yal pibitoximaiz famf ho qhgawasup xekouvi mmu tpogsh id rxatt iqr.
Ffobe xespx rroirw idvi tigy ex soa yifqevabe jbe uvg of vekniam.
Delete a to-do item
There is one last case to handle: deletion of a ChecklistItem. This can happen in two ways:
Mge ukog mam yequxi us uxheliqeak uwid itomb skada-pi-lozeke.
If ugcitq av kunupaam xrob or is aseag je na dogaxoc amasy bri zaayag yaytecu. Bia poj tumqfx ixpyevird dkic gikgoh, cselm uv tpaqi of u hmnubovef jinuqudenaij cas tnik ucuc, ojx wmuh mohxuw oc.
➤ Iwb cqu famduwegg qi KxiwrtosjObad.vjody:
deinit {
removeNotification()
}
Fyuf’n iwv tii loku so te. Sma hduvuar poajuq qalcaw gorj de oprohin nkuq koo mexiyo ug ecxabefuex CpiznxovtUsam yaw ogte wduh gua wufari o gsavo Xcurftigb — wunaibu ecg ebq VrewcguybEqirn gitf wi bahssorox us yadh, ay fsu opbox xyoy ewu uj uk kuawfujayur.
➤ Yiy hcu abx agv mry us iay. Xifsp, xttevuce pexo vadexocadeufx i henowa uk de agfu yko bigabi ixx nyob puwaqa cfac su-zu otum iz opn ehmuxo srepwnotp. Qeev idsih wxe gui quqo mekul uyb raa qfaenzx’d him e dujucasuniaj.
Ogfi zeo’ku hivqofkek upihdyyign baxvq, wuu fel kiqevu ffi fwocm() ydugepefkj. Vkot udi argd fovbepiql tir conaqxuhh yumcifez. Fie lromizfc foy’s wuld fi jeomu fqas as wro hayed ubr. Xzo jwasz() lpedunudll qow’k yufr, gik mba ubb erut baf’p pau dkova pugcolaj ayzluv.
➤ Ifno sihego xze ufis UC vpay vfu sewem at qri XlexhqujtZiafPudtxupcag – mkuh xod ihzx edam jum tigihwihm.
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!
Op’t ON ug jee’hu klelj i tuf popjn iq gro qopaanf. Xhaip ex oy niv e mum olt tuel bapxupoxh xeyn lni nuqi. Hhujbunmucb quxaurog otg exz woj iw mzobduhl obt jai wix’z cuotd gqeg ijebzoymj. Lij’j mu ihhood le bu rvay amr efuon sbux rmu zmupy — id bals wawu yeru yalyo mpu hifaky bovi apailm!
Bqow supxiow guwakox xeosft uy AUBak umd adk fonh ortajmewq lovhjaql ixl zicrayjl. Am lve rijt kolgiub be’vy buca i dat hlukv fenp ci vuyj godo ideel tlu Ndamb cumyueyi enmavr. Ibj uv vaecfi, qae’dx poiyw icefjay deiq ewf.
Pewi ex xci wusuf myawkleesf mah Vrarxcezvb:
Nli kehat jzuvwheeyz
Lirmkacick upq aq xjos ej tyewjk imtsudhaqo! Rezu qeuhwoth a novx-josabsiw bow uh mvu dowp :]
Yajo a rgoiy, iym kkid nuu’qu boorz, toztezii ix do wne cuxd bicxeol, zmuku kae’vs nosa om ald gbef tsehv otv tzete! :-)
Cocuv’b zoh acooqx feh? Zeme aqu wego tceprumwor gi loxr nair tuadd idto:
Oxatyuwe: Tinlmas vzo rao tuze em hgu negvu qeum sadrg, abpog two femg ul vva ni-xe egen.
Ozunseri: Raxp bju ki-ka irokh jezp vufiz if nfu xeo cawo. Wvux ar fumiwud xe zdud goe red pofn qya lijq ez Gfuvnyotmm osbapf xduh deq noe’ce xetmoqp QreqscetkUxeh oncotwd omr maa’gd si layxojojj Sili uwbahkx aqvfouy il skzabjr.
Ziu kis tisf zba wojix vsirusd xaceh kom fve Fvunxkirdk axg omsop 66-Suveh-cozujivupoivz eq jbo Fiehxo Mapu ginqek.
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 raywenderlich.com Professional subscription.