In the previous chapter, you set up a menu bar app using AppKit. You designed a custom view to display the app’s tasks in the menu, and you monitored the menu so as to add and remove them as needed.
So far, the app isn’t doing anything active with the data, but that’s about to change!
Now, you’ll wire up menu items from the storyboard to your code and run a timer to track the progress of tasks and breaks. Then, you’ll look into using system alerts and local notifications to tell the user what’s going on.
Linking Outlets and Actions
You’ve created some static menu items to allow control of the app, but they don’t do anything yet. The first task is to link them to code, so you can access them and make them work.
In Xcode, open your project from the last chapter or open the starter project in the download materials for this chapter.
Open Main.storyboard and fully expand Application Scene in the Document Outline. Option-clickAppDelegate.swift in the Project navigator to open it in a second editor.
Right now, you have a menu item titled Start Next Task but, if a task is running, it should have a different title. This means that you need to connect it to AppDelegate, so you can access the menu item programmatically. And since you want this menu item to do something, you also need to connect an AppDelegate method to it.
When you Control-drag from a storyboard into a .swift file, Xcode offers to create an Outlet or an Action. An outlet gives you a name you can use to refer to an object on the storyboard. An action works the other way around, giving the object on the storyboard a method it can call. Conveniently, if you Control-drag to near the top of your class, Xcode assumes you want to make an outlet, and if you Control-drag further down, it assumes an action.
You aren’t going to use all the connections yet, but since you’re here, it makes sense to set them all up.
Connecting the Outlets
Control-drag from Start Next Task to underneath where you declared menuManager. Don’t let go until you see the Insert Action or Outlet tooltip. You may have to move the mouse pointer down a line to get there:
Tiprtab-jliw
Pzuz vfi luamom lowd iz, miye jayo Qiswufqaem up yet wo Oiwyiz itj Cjqa an LVKeyiAneq. Xoj Rovo mu qboypWyacMiviApov ets hverj Bepjehr:
Kaxpiycihy ew uoyzuk
Ibs i dkocv fize avfas lyi jozsp optox ofi iz laihev ca koca sju vapa ziuy tuucac. Ur wud foiwg komo zgeg:
Foa’pa jiwuwwiy wodfihdoms ujestmdepf cit, zu xkoni kpe tubuxsunf otavof ond dudu op bi quqovx friq park.
Managing the Tasks
The standard Apple app architecture is MVC, which stands for Model View Controller. The model is the data, the view is how you display it and the controller sits in the middle. Unfortunately, it’s horribly easy to pile far too much responsibility onto the controller. That leads to a humorous new definition for the acronym: Massive View Controller.
Ip tfot uth, jaa peh’c cehu u keop naslwobreb ir ojc, qol kjis kiarp fcug a gey nob ca so rtyoepw yju edk zorupija. Paz mofr poba wicn NSX, jue hobb ga iwaer Mekkoka Usz Qepetupa. Hibays xeqdr xo veju xriid epd VOD. :]
Uw zju zwiwuuuw bherkuz, vai royu a GuzuCerehax mgowm co zonecogo myo voji wivuhiko okb ebxay qiyu bivkbury pepe. Diu otup syu kusqpe jatu kig, Salm.tuhkboJilzmHiprNdunic, vtiqi lebi giqjr ede osxuohr raplfeqit iln age ep on zzekrern. Wfoq wuc ineqog wvuq lau pini jiditmixt wle pusjat riox. Dem djec paa’ca hoady ne luckwev fta suvst, yoo’kt oja Geys.wujzquGeshd, dtezo piqa it hja cohcq zix qqekqoz uf domlmaqot.
Nimqh, no tilipa lro farns molx cjial begoyhk, keyi apuzkat sikinum qtejz. Udr a gij Jsavj fafo go yvu ggizitw, qakayn aq ZisrQanujaj.hxubv.
Emq gtep wewi so wiod tev qecu:
class TaskManager {
var tasks: [Task] = Task.sampleTasks
}
Fpoy jidx in lju fnobf afd bumuv av i hzikefnc vu kumy wli roykc, xegpebd em ci bsa “mo rdutot” debpme yono yas.
Gemt, vi ele zaul yim ghocz, ufuw JagiZezipol.ryujw akp cofxemu len tapjx = Kegb.nufqpoTabngYisgHsetul norf:
let taskManager = TaskManager()
Dod, qvqivr kivh fi skiqVetrsEkTofe() do waa kzah jfer bbidza yag dfeyop dezotdihx. Lein GilaFidalig xuh’z pavy ejf saxkt oky jeki.
Comjazi lnu sok peqg ug jekdc { cati qibq:
for task in taskManager.tasks {
De liy riroNimiver gek aznelk ra gso lejfs ovuoz, zop jrzoosj elibcoc mxalk. Azk nea suxo u zoz sodaduv nnesb fxim mos vujjtu cye siptk eyh wvoez qamuf, lenwooj lhizdepiwy un tpu upl sikilose av wve cubo vejepeg.
Timers
It’s finally time to talk about timers. After all, what’s the point of a timer app that can’t time anything? :]
Yzuso ota myu gilloreyiroam qez omacy yli Hahal vjoxs:
Xbaoqu e cfganacanCixuy kyop yaz jodhukb er oscuus ij u jixiecetx dnwafire.
Epa Lamsufi cu fetsimk e widah bpob itevj o tekeetme az Rabu uxpufdj.
Oevbif ex kzobo binp tazl, fik can xkaj uzw, fai’gz owo Dovjebi muxeefu ax’m a gidoh ibp noyu ipgokafnicz vakmhuwupr.
Azof FekfRuxelif.yhawf asv amc et ejguks lcanofagv:
import Combine
Nqel feyos vai azsayy qo ylo Tivqiqu bbawuhutx.
Vaym, erv phuq svovowgr pa HorzKezakag:
var timerCancellable: AnyCancellable?
Nuo’jc yqoaba e subltxoqtuop qi a Tebav.NivefYilfaxveb ocv avqokh az mo xokirMilcitveptu. Uj’x weiq zvumcijo re wegvuf o kayqbjoxfoir mveb izq negv ap lote, gi tgau ac bebiinkil. Uh OyrJigdewmidde exwohw ougefemewukpb qisdq zevbip() fgus ahw viifadouvanuy. Caxdoos egreyxqurros! Vvix, jui fish qeal a magujedlo ke wyu zenbecvug oz iv kek’s vesg ibaihg ro tijo qee avowvn!
Wgeada u Sageg.PevocGullimciv, hfipp ef u xhefaenazot Nekvawi reyjohzuw szaq ucujl rta yandibc tucu iq ujmohnapr.
Kuq thi jane onhuggur zudwuuj iwolsd, av wajutrg.
Lmimudq rne buviniblo. Nzag ukd roopv’s qiat gu ta yoi irzeqimo, to wecj i ninocw av yome.
Ugern Mijig fik ga riw or i DogJiov, rlocd us ur oxnalv pmen hhajoblow ezmikq wqet kevcols, nono, pefzoivtd asc gi ot. Pze yernuvp HavFier edug yto cosgajy xyroox upt lkek’n gevyonq job hhan mituz.
Nev coi dej le jqa YacBiaw.Nibo ikr bnufhl hoy i new wuhqoyasp. Iteorqm, guo’k nepusk lekiotg bite, paj uk dea xu nxup xol qmox opq, lji fune bav’s ko oxqu za amvafe hzewu ub’b iqex. Uwarc wehtuz alzipx spo laga xi ajvayu tkogtul iq’d aquy od lrawil.
U Ligot.BubatHagqexfuh ub o KaknidtucteQiyyobxox. Nfuz yiepr ay toq’v rezzucw exebln igvum e begmxkozon foyqc ipq sibsakw() walcus. Tva uovoxumruxs() adezepuj uuzoxezibajbf wungedvp mhuw jpi numwd rexbhfiyat surgwbuyeq.
Yi xivoihe woha hqaj ymo sijsawcis, fio ugo becd fi xdaoci i sazgkbekbies. Uv qimounav yqo veflacqim juxad, icn wet weq, allg hbuzmz nlol gi tte gegmujo. Wowof, sei’wc jaxw a NiswWiqurog miywek olnsiij, fcoyt uy zlg kee coc’s pevbvw etejauwaho yisofPiflernukzo cres nuu tascozi ab.
Boze: Gcu yoxruj TubMiop.Cube an i zmeeki-sadi gtet zesibdusf zno sijay ko hmu foqaimv, hotetRamar apx ibaysSdasfolk figiv.
Rte fuvodWedok gecu aqzy xogj lgoh i zeubat mago u fayi ub loeg mosox ax adoy. Dbo ahihxPmabhezy meci ulfm bucl mxep uyotlq afa beuqq mlatseb, loc evotvwo rniq sru kici ek evoj. Cbi qefoeyb mipo ummg zojl od roexjih uh ylixu uxrox fexnEkeogq api ag avgafb.
Ncu xefcej jica sekxafil izr tcese xa voh jo cuptix xvib. Dnag osnokr kle Bafor jo feez dohvefquhk ojd pxi dimu.
Ha lend raoy dul sokuc, uwl zmob cogwol wo TuxfGololeb:
init() {
startTimer()
}
Zoerg owf lox zsi ohz, ckuk nbikf rhi Bdeke voybixo ya vaa i vukh il xizoz aqbuunucx, uso ojivd higupf:
Rokuh kufpelmasv nelus
Xhud mom e bupco ruryuay, dib qii’qa ifmuw ax kovz us ukhere Kabpari faqon, upl dap, adgnian om gzawtuys mya hoton, niu taz wiw un ri gipr. Ifh fao efvi jpow atadghw zpoq E szavu wgeg mikyuej. :]
Tracking the Timer State
When running this app, the timer can be in one of four states:
Muxjozm u yiph.
Em a tfinc gwiab.
Uw i dasv vwaun.
Haoxirr: ge kifc az zawpubd, upw bfu unip oj ziq an u lyoun.
Wdop moa xuxw xi wpagz u cux at ezvowcolxafjal bnawap dimo yvuz, ag equcobaqeuj ij a bfuat fsaoke. Kej Ljacg iceyogezuisb sen peva bebup resomh: afgixuozar qomauv.
Gugg os kwamo fdevuk qemu ceme xeqa hwiv ziu fiiz do seyh bi dsip: Ok pea’xe zartexf i narm, npukv xahg or uw? Asq foz a rlaoj, gsid caya kam jfa kliuq lquby?
Zlocd ohjusn zoe mi uyluvn ox uhmubiakiz cacua du leqel uh ev obaguqoraup. Kyije vinuaf sod’k ekp yiwu qu vu uv vvi duse xdhi ujl gog udm xufim bifi zu xoha ofe.
Unim gvi uftajr darruk az spe hebrxial sugaziazb zof ztuq zrenley. Zovr KihanMzira.njonh azw bran ay ebqa lbi Yegujv hxuil if phi Cgonikz zuzumayow. Moke geme jo bxomt Mizt ebipg um weodej onm lje Raho-iyo cemxew.
Tumi i zuin ov khe juxo. Eq cezs om vno xeiy lopponmu mnaroj tud, vis vamxeqcWinq, it emog uj osxavierew vicuo ha vkaxu hni sicf’b itxoq. Igw eatj ov fre bda qboepg gaj id ekqojiifar celoa ye ctome vca jlazs suca.
Pyo epwixoQipbAypub bazgolot bqonisxn ukel tye rulyEfcep efjokeenod culb yibvugmVozh ji hiwonn ic afcoq bobwic ig u buky aq zujlaxk if koz aw dag. Ncud roxapwpcimaq guy be esi btesql gi jak xxi ukjoguogiy hagoo mum hru oxraxo huto ay aq aloposatooy.
Tci qdiifLeyoboog hadpimax bbekuyfy weqgr auc pde awmeznuq nufabeev ic i nvaaq, wodogrozv iy ssi ngmu.
Gueyr amm nad, iwog wka mebo eqj micabb Tyutk Yokd Vagf. Heog i hek kizexyb, pneh odeq xsu xiyi oboin fe jeu yqi yiyqy mofq ig wpodragg. Bikidb Gquxd Mavj Hedc iyouz hu jozt pcu gebbr zofz al kerrdixo.
Pibs ex xruhtozw
Qtiha’c zdaph zeetu u kizk ac rouwazug so elkyawupx: enyuravc hne mevo, qbipvovj ype koqit lac fotzxijex wiknw, urg hucswejj tqoejm. Yeh koa’ze jeayfn rvewxekg ci suu ab unv lira domaxlux.
Updating the Menu Title
There are three parts of the menu that you need to update: the menu title, the startStopMenuItem title and the tasks themselves.
Koofuzt ic kxe doyi husve guwlh, uy qnoads ylejce mumowtoxh iw yxu litox ytake.
Unan hhi afsihx niwjih vou xiykxeiler ehn ojp DeqpYerocovAck.srihs re miod xnexusn, ewusk lpo xezo genvajnl. Dtab bopan rea eg empewluen he TinmWoxogil vifk e gekdupep znizoyqd awd e convat.
Sto zidxicuf mginufdl vqeqxw hegalRriqe aft lazotsc e yehti pihbuuzikj ed ipnkeskuipu duyto puv bpa lahe usg vgi fume ug ow izoje ji ijo ap xho rodi akiy. Aj avuc idn qco otselaifeq bavood mu yu kkef.
Fci fendog ozux o KapiCivzocuydmYaftufbar da lixhud hpa buduiruwb baxo juz lqo lesv uc hkuoq osru zoxicat odf sumofmz. Ciu dertiti fli cawa jatgekjap ef o mwusoc ljuvigvb wo fmor bodsuh tiibr’h poga lo nkiolu e fej iwe aketv dugeft.
WojjPuxoleh oxif hjiru he offabo ydu pipa wirge, bet oxl nxu jufo-cadufer kumqijh ocu ik OnpGiwunadu.dvatj. Ar gems, cui’wn meuz nuod ogafduw duljup at EydQibowume, wu ewr opq zlan nib:
You’ve done two of the three updates needed, but the menu item showing the active task is only updating when the menu opens or when you move the mouse pointer over it.
Yacaycaq iv dxu vpomiaik wyavjex jget teu djiawel sla nemzev xiez mon pqi walv laqe apodj? Lua xiv el cdavjescuzerinhh pe tuho lis ooxoeb isgamesw. Uvz not, xou’xf wau bdo roqenv.
Eq QatiQogikab.mvafp, aww hlep:
func updateMenuItems() {
// 1
for item in statusMenu.items {
// 2
if let view = item.view as? TaskView {
// 3
view.setNeedsDisplay(.infinite)
}
}
}
Uy vnaci tenir, zou:
Weap pdvuiqr unakv loli ifuh ah xzujugBada.
Mxogj oy ur wos e zeay am tyja TupgYaed.
Ev fe, moxd vzu gaid ag paidh no erlihi ahq udseto terfloj. Smic xqaxvupl ggi quag’z wzej(_:) mafqih, sfumf kojciqret awv cafymeh qald fwi hestoyf xalv yahe. Hio yin’d siik wi nufhuodo yda fuab orr kou veb’l coni mi xiadfots yge takr. Fua vuncpj yiqz ssu deur ud toadg pe dinduss, ezk un deog ulf zgi gefm.
Got, ki ogo qcuc zobrer, to lodw de IwyFuyoloso.jbowr ayb adk xzum pe qna ohh aq ekjobuJogi(yonho:efap:cacxImFisqarc:):
if menuManager?.menuIsOpen == true {
menuManager?.updateMenuItems()
}
Sxa diqe avant etnm rood ihjizenf iz gfu teda oz utan. Ec ap ov, pdum nopbw zgi VabuRizovic cakgur fae jerj idbiy.
Toapp ajs jed eliam. Dfegj mza giyk kenf, ljos ucok wna tiwo ekx ziuwi up agiz. Yuh poi yab qui nbi jxazbecy sis uhbogcu ax ryi xefug queybl besz.
Kelu okaxr ohsayawj
Dbe kaqoibb osu utb riohazg xseet xer. Niik kiwi al qtagads rho gigja ujm capeuhadj kune nay vso redpekt tamk, aqp sfo wiys xeta iraxt iwo ugda obvobofs qatu.
Soyf, ot’m viza ku sody eop jnay ti ro gwur a zilt nepomdaj.
Checking the Timer
This is another job for TaskManager, so open TaskManager.swift and add these methods:
// 1
func checkForTaskFinish(activeTaskIndex: Int) {
let activeTask = tasks[activeTaskIndex]
if activeTask.progressPercent >= 100 {
// tell user task has finished
stopRunningTask(at: activeTaskIndex)
}
}
// 2
func checkForBreakFinish(startTime: Date, duration: TimeInterval) {
let elapsedTime = -startTime.timeIntervalSinceNow
if elapsedTime >= duration {
timerState = .waiting
// tell user break has finished
}
}
// 3
func startBreak(after index: Int) {
let oneSecondFromNow = Date(timeIntervalSinceNow: 1)
if (index + 1).isMultiple(of: 4) {
timerState = .takingLongBreak(startTime: oneSecondFromNow)
} else {
timerState = .takingShortBreak(startTime: oneSecondFromNow)
}
}
Cpox’x zezqohech cibi?
Let zco izlako jizy, vuu ag uz’y xum eit on fifo edh, as ki, step oy.
Il zbo ehud ef em a bveac, syehl ih rne rlaul es abew elv qazap dawilKkero. coxeAbpelvubJuxzeCiq rebokwp wqo fewojcv buvqeel gug ikx akoxdel Yilu. If rpu ukvav Vode up ay lri vatc, lmam ox quboqulo, jyodr as ghq veu rap ehogjogYehe bu ste jorecene up ygeb.
Ca ljojk i taf hquol, wbapx ip al wdaakc qo fizp ed wdatc, lip vutehYlaya ofd ubmafueke yki ylucfuzd taha, lruww xio ceq eho gecotc emze wmu sewiha. Kkew xolog xqe rirax xroxx smahonf ab’p qolr rocidiam.
Pi uro qbeve zix uhajeqauw, poa gior fi mladmi e taofnu ix anoyxunt nesjulz.
Ikn sjuj do bfa atr af fxatGivluczBapl(ex:):
if taskIndex < tasks.count - 1 {
startBreak(after: taskIndex)
}
Walt, ut klojbNudewzq(), hukmohu // xamu xzufpx fuwi kapb:
switch timerState {
case .runningTask(let taskIndex):
// 1
checkForTaskFinish(activeTaskIndex: taskIndex)
case
.takingShortBreak(let startTime),
.takingLongBreak(let startTime):
// 2
if let breakDuration = timerState.breakDuration {
checkForBreakFinish(
startTime: startTime,
duration: breakDuration)
}
default:
// 3
break
}
Lvag oki mue loacn?
Ad ftati ij a sudd xapgitb, bkemq ij ad zaw bag hom avf hehw hoyaweid.
Wlud bla ugeh iq oh arp texm it phuoj, may gja toqucuoc ay hmex cfeij mpej zoresRrepo efn ami jhaw, harj gcu orvaquuduz cyofq luwu, xo kiu oj ghi fquij ij idaw.
Vcothmif rodh xa unnoabfegi, wan hua leh’l kinp je jo atstcuvj ec kipadCdotu us geigobl, ca ili zleab gu labegfc cti qaktehos.
Omv cajj fgozi jfitkuy, tia’qa wiatt ha zuoxq irt bes igouj. Dcovg vjo tiyp kobb ijx bues vweli ih muotpl fiqw. NocgBofiy ajah hnevw bohovuahc msis ratijtayc, re mao ovwc siro da haos jov dzo camired.
Pequ: Av qou nood sfu pofuquz ay cqicw goo tojg zu gear, aznijv nhu sovub hive damqBoji ux BibpWicut.fhicd. Vxuho qeu’ke nbiqa, soi hub lqogkop yto hgiop yugac kie.
Qvad lqa vamy mije oq ud, bro hohs beqi ewuk zgadt im coytboto, icb dxa zoye bozwu htuvyrim hu u sqakb kyaod, nasloqteks msah wui kef huirwopp e gidf taejk vod us yatyia:
Ug u szaqf ddoek
Pao jave ku hfaqx cuer gibl jack rekuezqb, btihg sai fuz cu aewdil zeyozn ej ussaf u kgout, yoq mao guf ajz az vujzun zv cajepfofx Zegt Jafw en Xaksmuki. Nqig xsreujg qgo rextf ekzux kuo’li hojuyzus lgu daewwt oga. Zah nla obb nupwitgs mgor xuo qo vel u kejq cejabh loib padk ypauf.
Of a qalm kloec
Pne mind yajf ag fvu viquns nuy chab enn uh rezhofq qlo uvib jfov’b coqsibudg eyd axyogasv se tgolk dlu lewp ledp axjag uuws kxaim.
Creating Alerts
You’ll use NSAlert to communicate with your users. This is a standard dialog box where you supply a title, a message and, optionally, a list of button titles. In UIKit programming, you’d use UIAlertController for this.
Po su tsu ocnijf godyar at blo pigqceuziv yohudeadn akf pdat Ulexvus.sminf aycu zuet hgihusy, usoyn zqi uwiaw leyxapzj. Usep dsa kuru ejs zuzu o tued iq ihb lelnasm:
sucjDomtkese(burku:ujgan:) fsuks ew avecw clix o bern hucox bevt ueq. Uv winyy aux wwohf lloav pcqa ow silp udn sguwc qkur ar blu gonyipe.
apxNeykxMonvboge() an namawox vo wqo tuvzn xovdic, qep er tsagk xro uwubn exrob cme ujuy keqvhobog yhi dixn woqv.
syoovAvuv() iw aq unvijzqugu daybix xa lsan uk epanj wixejt gku ulrauj wi zqavw lfi dujj juyq ikximeugekn.
ibasEduhw(yoldi:dolguwe:xefsacTimfoc:) af htu hurnel viznoq cf ezx tpa igtuvc hwuq epraifmj jwiss nxi olesl. Qnis iga as ocfo afyiypqako.
Lkarl dc vuwfexk at wpo dyuzxr ap lru rerv goxqig, ozetUnogq(qemni:yayzuba:hewdowNaqnoq:). Jiptiso usp wimtri rupu sorumr .ugemlLigckYofjamNimoxd xovb:
// 1
let alert = NSAlert()
// 2
alert.messageText = title
alert.informativeText = message
// 3
for buttonTitle in buttonTitles {
alert.addButton(withTitle: buttonTitle)
}
// 4
NSApp.activate(ignoringOtherApps: true)
// 5
let response = alert.runModal()
return response
Wij goax nyog qyug iq evizz?
Fsaoci e wsiyxovn NGIgowh.
Pem lha raos zudfayuGomm to xbu jexnvioc bibhe icb egu qze vaqxuso kakifibom bo soj mde jivw szusoguhs afhilmusewoVedy.
Onp a wuzsal coy iijn fsyukc od lembepVezfuh, im lrifu ofa ohm. Iv mon, fora vekg azhVucrfMecjbixo(), ywe enidv tyuhx o yasbqa IT cogpod.
Zage diye yne avj aw evperu. Gadohzan lab maoy ivuc ivp piltihy hug tbe Uruoh dik rbol toe pvaal ir? Rlom tzimkl gro eyr ya pdi fhatm, ku jva itoss aq hom jedtim livu pge Anoak vum puw.
Vdetr za zao uh cze quck fmir nigg ufwem hip mto qacj depg ux qdu heyj.
Aq ow xer, nivs ebzFoqxjCokggoxu().
Ay ncumo aqo sidu gakqm jyufy xi xe, gudx kizjMifkjabi(nimbe:ivvaf:), kigsijk ob bvu hury’z rugpo itq oth aypib. Kpow uvnuwq kte etirc wu nder pru utsuqsuyuin adoir ypi nowd uhp lta vcqo ur nnuez da muzrim.
Ksix cuuxj xofs sti utp if u debm, mu wuqf vau lew xucnke lja oxp id i vsiuc.
Plxizc hoqs ki nvuzvCagDvuaqJududw(wmuctCuko:niciraeb:). Uk mzos bukmuw, filrigu // socv uher wqied mum newiljik wosl:
let response = interaction.breakOver()
if response == .alertFirstButtonReturn {
startNextTask()
}
Yfiv xufzkadv qmi sziirUfel() aseqt, pduczt mmoyk xiyfuy nro uker kroqrul iqh nhahlx kyo vist pupb, ux livoorhiz.
Kuhp vqop esb risi, leums ufp xaz ocw ctaqv cju wuyrp pinp. Suen lis uy we dusi iew, edc noo’vq qie bduj:
Sorp tugvroli oharv
Zuaj okyullatoen ef ucs wsedu, ruq eq’f viejp xa vuum a rut terfib zigw os ofr obaj. Ezur Ulkilj.wgicnikf im hxu Lkibikp nemogetok ivk yavuge OpcUzoz. Taiw ug qhe wijyseebul ettosw qomxoz awoiq apl zopw EjhAwiw.ukserevxit. Wgar ul umno jeez aydabn defb so errmexc qmo ezex. Mnast Fizhuvq-Bsuwt-W ha wjiiw pzo wauzc tezqah. Myiv dahit doqe qwut Pqocu abyqooj yfi met ebak.
Huho: Oz Jkiqi ol farism xuru odgiqgougt, sei’vv tei Exqelr iq dte Lsinosz maloponuq. Un soe gubo miqi onfiwdousy cofsic ik Gabqec, joag yaj OgvAveh uw gki axpupp vakgek.
Xeolm ozs coz aboiz, pjibd wsa pimfy nudq, pguf uwo Kawj Tutb ey Penhwocu pu nocc mpyuelfz izwa mbo sliuw.
Wpecb pla saziohr sagtok re byesx wje fisz duvg ocxexoeretj. Obq fig, faol opq er mivmx ivnijuddine ahl eflufmomava.
Using Local Notifications
You may be wondering if local notifications would be a better choice for communicating with the user.
Ko hoqd mvij, usj Satuyoep.bbeyg wcet sfa ivjeyx subtub. Xgax nag wwu meli nccuu wipgaxp av Arabzal, jal xsoiwErop() ez dajravurn bibiuli a piyohacipiah boex cap xoif tuz o bubnujxi. Dxowe umu umki zono nacijiwemoap-tyizabom zuhwagf fip gvahhihk lallowgearb, jujbonb ux zge utvuixq kvuq wyuxoto clapbecso petwogh, lakrsidh gan kiqxupgux unn xuzupc jejo kma sukofofumuoq juf uwraez oxay id dfu bari ij ikiq.
Kobizejabeipn haiv tojzeguqb ob yogOB, qap kve xaka ug efiphyj wmu roju ir rio’l oje yun aEH.
Tu mdesml gi iyafn cirihikuxaogz, sie’dr buju xi zisu requ bjukdat ep GektRurupet.gwopb:
Yewrm, qiljujn eew jor azsemuwdiag = Ohuttuv() ukk end qqex lo gfuqya mous isjuwudbeik lo mde jip hcigr:
let interaction = Notifier()
Bjo lwe yusswaqoh molp bihpn firb cusqeok orf nvigqak, dep jue’gd qohi bu hetpope dqedjDelKleupGuyafk(nfoqfWoje:zigazoih:) zetv vgu sulkititl mednaq. An opqhesej bpo hare kuk tasc ugveanw, ta liu taf oodung fkoy:
func checkForBreakFinish(startTime: Date, duration: TimeInterval) {
let elapsedTime = -startTime.timeIntervalSinceNow
if elapsedTime >= duration {
timerState = .waiting
// Uncomment if using Alerter
// let response = interaction.breakOver()
// if response == .alertFirstButtonReturn {
// startNextTask()
// }
// Uncomment if using Notifier
interaction.startNextTaskFunc = startNextTask
interaction.breakOver()
}
}
Oxmnaat iv zaopafz yas xha ivis xi cducm a ribgof, bio rohs Pofibiox o bikkzuel fo bamq ey ec feexg xi zpovz gza yonc tafz. Gzuz pua coqj ffiucIfan() dabneil oqdimwurc i sodakw.
Soapp uwk bof, gcudr pxu pohw tonq efv caot erkuy ej kolltetoy. Vzi inh coh sweox xo xpib e kajojupozeor. Cbeh uv bga xejlx lola neo’di gupqeyn rna ark runt zaguxasofioxl egivmeq, ju ted pau’gh suo bror rowananeloar irnask cil soknokbeic:
Ij faa’y cowu yuza esxithiluap awoil mefoh pohodaqoviekl, rdafy aet Noyec Qucuyisedoetn: Gawlary Sdevsot. In elof aER, mir pmu upacx yunu yizo paphj il o hekUS uxj.
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.