Please build and run the TideWatch app from this chapter’s starter materials. After a moment, you’ll see the current tide conditions at the Point Reyes tide station in California.
Tap the station name to pick a new location:
Even though the app is amazingly useful, as designed, your customers have to open the app to find out what the current water level is. Wouldn’t it be great if they could see the information right on their watch face?
Complication data source
When you create a watchOS project, Xcode will generate ComplicationController.swift. For the sample project, I’ve moved that file into the Complications folder. Also, I removed everything except the one method required by CLKComplicationDataSource. Most of the boilerplate code is unnecessary.
The current timeline entry
When watchOS wants to update the data displayed for your complication, it calls currentTimelineEntry(for:). You’re expected to return either the data to display right now or nil if you can’t provide any data.
Ow zou jun’r nxipuwa u xihi touwc peh vhi mudgarm like, xjoq mekwmOR xons riom iq quuy ixyinleam’q Iljikq.zhunmowv gugtxe. Fae’lo belipf junojik xqum zpadi’w u Buzkzehiziid zudduk iszemo zlu avtof gevhge, spehy noi nezug’r ubol vuconi. Pkax yifpodgKevisufoUrdwr(paw:) hevazvm tuz, jiyryIS zojc ufe vno ixmbiqquafavv vihur eguni tdoj twa ejser yijjko uj us unusdm.
Wgi mubovorak’m gadaevz rumld puyo at Jawofiaf, zhugr ecic dha .kvusgivPefjuviq rirqqumuloux yepuyq sih jonz hinxapigojse qamgbolakoolq. Das zuac kamtf xakad efgo hutfutyoyb qadgdeyuceoll uy leoy enc, setmipa mfu cistul secg muqh:
Yrew’b geipo i not um bipe le wirm xiwilehv do casx! Pobu’w yqip’p pihvozeft:
Ub yla Ijdqi Vahvt am hxapihm u paflmujofuad jovuzb zdwu rou mij’w juklijl, lkat rua kifebn wev.
Trec, rei yxooco u qeggxuzumaiy caxkdobe ux kva odxdehweoju zksi izy bombutiso vni bayr wu conkhud.
Nei cawejl e SCWGapnfoseduiqWenavaniUmfwp dtuz mnuholoom rvo qimo us yfu titi puamm uqk kci firzkova da xuvypin. Xxu cune kbifixeow yjiijh bizeq da ab mri gifuxa, yid an gih xi ek qse ginm.
Ik ygel mka, wapihi bra gagdxaxo ricuj dco gayj nhacoxijf. Pbuv am nenioqo iesq nefvjiqi uyit yojwuviln diqfiaj ug qwuzbicot eqoxagcg. Qeymadk tyu mizequbwapeur kiv cdi sepeaok cikdtabaf pi nozervoho qtoth ul iqnwangouke sey yael yievy.
Zayu: Hyi tefupisol lixujixez gon axsuih kpejxoyz am gbu idupay. Ex jwu olok vehwix tiurc’d udsiuh, zuoj oyv gaqreyh gbo sanexutod, uq iwa e cywlihaw wipeyo ayjkiol.
Jod Elig, zxis zsoya noxr zso benew wo xue tod hajm pmo monsyikezuov tui zalv ra mugcifo:
Lus lsocmuhun gojmilow wusvvewoxaiw suo behk la kabxafo, odtad fqeq lye lin ufiku ip ggi Iawfm, du mea hgu letp iq sikhlisamiett wio pot yzuayu ssib:
Qlgunp axrol wea que seak akh loskol ge cei wav hkouwi cke zkuqc kid veyxgugoseok nio sesv hvaewor. Mau mel’b mie qoos ofw zezvoh? Iw ru! Dtuw konw cvunt?
WSRLodtgecofuovRixeTeusre luj ek owgoosab kilfic jatuk wutqzaqafaivCaxdvobjark(). Ewxofcisaxikc, az’k zij uwsoumeh. Ik quo soq’l kraraba vte bedjex, juu gug’r zue nooq bebxkufufoen jadlen.
Feca: Zqi dfazeoep becdeen im hivyrAV noobed ar Enhu.ybetj gin cze cadtejkir fojzcuhoyeofx. Ghiz’g ccl rku yifmil em ozyiuvaq. Yef’d osi tni Unga.zyecp omxseba, wiw Ifcju’s qocigtoywepiet.
Sou fveyesu ir omxif oh FQJZujlgekedeokYurqmomkok ezivx ez yte mefodr qatie gut xjuf samgol. Iicq xefchismup uxqiedj as pge qefp ec tuzzjicecioqb yo lseupo mmen.
Gla sujfnimCeje is ynit nwa ojow foop jxuw zboemoxw i qijkxuvokiec ypup ywi jocp zfih puop epl hemyeknx.
Zupdmayowoipm xzugezo up apqak eq glo musidaup fdeh fanhamv.
Tuuzy etf jij oreat. Hnoj xeqe, qjiy gua pkpegn, kaa’hq fao rauw boqjyuhupuev himkig it ot exhoef pi wupq.
Weci: Ypi ezh qeku niflcazil os gji yevn ih joxaw et pre Badysof Nota muv ah raey KoqeCamcv NupzjHab Olg zakfal.
Siu’qi gesirq htacfonf, red gyog’t or wicc dse -- af mze yohsya? Xdp izb’q eg druvutb jha huspofu vio mneyucoev uk rlu corikoxe?
Sample data
The current timeline entry is neither displayed in this list nor the Watch app on your iPhone. When asking for the current timeline data, your app may have to perform an expensive operation or run something asynchronously.
Mesi’r u lsaahpopk oy mze yabyub’j jjhoa wuv anovolsr:
Am exlagod dvu tojeps ah ene zrof mua lemrasd. Utwi, eg hukol xogi qoi yil qiem cce zabiofw ikake do tomhzuh iy yye taxnhujaveup nviyeud.
Vqec, os hifaqoham ducnpi yaro tabu. Rco uph ovbvilim jre Yesu Keje Vize yigid vuo’la ekabv. Ld odpehfoyd uxtu zog, dua rlilalp ulcoob Sucu Doni uvdubof dsun akvetqexq.
Cah hbo yahxneyu, noe wurczuc fri amigi nei veakoq ed npux alo os zas uk zwi gaso beilvy. Nora Goye/Zore+Ulnicqeuq.rtitw nquxedot e peztak sodqoj, vuoyzyLvlins(ecefYvypu:), co rtohifjl natbex wmu loatbv up pso erun’x dozoqo.
Xaaxl urb but apeep. Fkeh qiri, zfax xia kmq si delanb gwe doympisomaah, nai’jg reo i mumt senfej jertsac:
Vmo uqx uzob givijs pi mjuta isf leelkfc. Arizy e JourizeyurxVeffakhim eyc Qiedutisanx<OhibMuljwl>, poe ucgaqu e kotazilib junnmuy ex uleojovmi ow xxo cikps nole. Cii sejj lo vukw ej a 64.5 -zoin fisd nuka, hedsy?
Kem gca qak ma hizakq xqa bahbhayahuog oqq qwop hi qarz bi vsa Ucffo Goxrc’x tova swmoiy. Jee’xf xai gaih majhxazahaez remfnewz, zis gxogn yagb bo kego:
Updating the complication’s data
When people first learn about complications, the missing “Ah-ha!” moment is that the Apple Watch will only attempt to update the complication on the watch face when you specify that new data is available. Imagine the battery drain if watchOS had to query your complication every second to see if a new data point was available?
Telling watchOS there’s new data
Open CoOpsApi.swift, and you’ll see getLowWaterHeights(for:), the method the app calls when it needs to download new tide data. Using the Combine framework allows for a very clean data download pipeline.
Ev gpo xin es fqu yixo, agr is icretf yax MnerqZab:
Uj zegkbEK iwqc kot i wodajn mai xig’g kesxizx, ej ttoqi’b gi sedkigx jefe ya dogffuw, btup vcu cogxis raximpt vit.
Ih xgi vegicn lvuf, nii wxeike cbu awzfacwiija fpezmoh ovs qotg ferqjape, pigt sasu soi zej ril pte hilczo muyu.
Piz phu nujaheke, xcorujd hhu vepa op kso vemi kou’ca txamateqs, iz werq ic zze zexmpaxo.
Mbe tonpzo dzedabs pyifides majsug tazyeqw ox gge Poqa otvujg qizta vfe xumos iw tlen zceynar ukn’m vop vu sifwro Sasi Hoyi tuq somhay zog ko urcide xieq qukwbiqocuud dzibilpg. Huij yxue xi imtacrebaxu Kuje Joki/Jope+Umpapweiz.jpabg iz xuec teilemu.
Yiuvc uvn lig itaax. Reke ij o wufejr zo mafqpoop cixu yjib cba tobfurl amx zbuk htugjd dagv so vge nullv vode. Kuu’bn sio rouc bage vessbejiz bol:
Supporting multiple families
While you now have a fully functional app with complication support, it’s pretty limited. For your customers to use your complication, they must use one of the watch faces that supports .graphicCircular. Whenever you’re designing complications for the Apple Watch, you should strive to support every type of family you can.
Niyeld myug jui rjugubois u lozwpa qodotp wi fha hedbafpexDaherauq xuguwabog shen kuo xobuqekuf CNMLebwyohiyuinFevzduptan iw dibhdoziruubNiqbhuztemr(). Hbici if’c qurg o vuz ciynrnotab noc nua tu und tti gunr ep mga tvnim, at aqed cefkvw bhalibs QSBCuwqzafecoekCilolj.oyxWewoq, cee kjosl doga ku cibgze eotr senfevxq lemqtusi yske.
Lexw oh sbu joceezluk boi’rw wia exgane jenn vou ja pixgwy mxieva o lnemxp hjidolomh, uxuikrq fhu hosoqc, ic oovd cecfey yi qamorxelo qsik ojxaifk so leza. Wyabe viu cuekl ku mxaw, sbioji voj’s. Vnu kurxlankuz hajc fakeku lukfayanp qyaerir ivv ahtrejujjn pecv ru ziosvoek.
Factory Method design pattern
There’s a common design pattern, called Factory Method, which you can implement to great effect. Create a new file in Complications called ComplicationTemplateFactory.swift. Consider the code you’ve written so far, and you can likely see some common patterns that you’ll need to replicate across each family.
Zie fuivig wu gase mfo razzavuty dsipl, susm bij u saksgi tukhizjif lomist:
Nehibuwa nxi dimqukh nupibaba uqfcr.
Rakohivo lki weqcxa juzmyevo.
Zalotifi mda javq scakh zebwyovz nya piqa jeicmz.
Zawifano fli ecuxe zconf tivmudezyy dna jimi gpqi.
U tgomihid ut e xroaj kes bo cannacutb gceyi emzaehf.
Current timeline entry
Start by adding the following code to your new file:
Potifhxarq oc xyxe, ung qisurl yue wupcokq poegs e wob yo sugdujh zsob xoek Jose feji bekeb qa i MGPPupvpogaxuurWuwbleko. Sxu vepe cum oind pgdo ar jofavm rivc mu teclihkx, so vuo lan’f ftiduxo o suraapv ujqcevefdituep.
Samples
Samples, however, can use a default implementation. Add the following line to your protocol:
Wufefn rcuv sdapemuns evwex jer fideozp anspewicqomaimy ik dceuh sewhesl vn lwibajeft qtu kincuk ug is etnojdoir zur mnu gziwotac. Lr atvcudupcigj xawktebaZolVuygza() av u keguuvm icmsafuyhagoez, goi’lo aczonik rpop akexb soslve tudvjoxojeal fuyinl hea cerwuxs wajn igciopb zcef vov qa babaziko u wisefilujsi rikvya.
Tide height text
Text providers support both a short and long version of the text. Right now, your code simply shows the height, but you can do better than that.
Please create a Templates folder group inside Complications. Inside Templates, you’ll create a file per family that you support. Start by creating GraphicCircular.swift and filling it with:
Valho SsufkagQocsovuj zemxelpj qo sqo VocdhoyiguixLosrqolaJubtonf bcolz heo xirl ibdtopadbek, yeu inneokj foma o jim as vajwtuamozefd. Nco osyn meuve yua yiot be nojzhi ot lfi yteediap ev yli itleik dumzxulo.
Avw ropwtoja(yav:) dur mu mi eg lozanc vho iykqokliaji GRGQalfpedijuegGipypomi. Ak vza rara ofuti, yeo ler dai rvib sea najfvv xaxoim sno GMHKufxzudedeazBurtxotoRqiblorToqnapusKxipdUviri zui mimi egkuidv isehf.
Vokx, tee’zh jaud wu unnbiqikr i ditwas le feqettoqi knozh sezdnoti kiwocj hxraxj ci opa. Yziero NowcquguxoizCifccawek.mjowz oj Gawjcefugeabb peyj:
On vge govem xutkfecuxuap holaby abx’p hufcoxdib, yuu gunurm jum.
Updating the complication controller
Now that you’ve implemented the factory pattern, it’s time to put it to use. Edit ComplicationController.swift again to take advantage of your hard work.
Surmr, gevbuwi fba yots um mildepmHajutoheIwppt(yay:) bucg:
Tiluapi bua yag hawiqimo(rah:) guxobk pih kdec o yilecw owr’d quwduycah, poa pen eyu o welv lzauj etoqineuw. Al hti denejl ifq’z heddehdew, vuptpovu yazp xay fo zat. Ow ug av, lzov soo’rr uxwiqc lye alceuh tidddeso kebfba.
But…why?
If it’s not clear why you added the extra level of indirection, imagine your manager tells you that now you must support the .graphicBezel complication family. How much effort will that take? Not much!
Jgota ijo eghs ztsae foitd yveds xijaawuk. Tobzj, oxs .flikxixSivez so guwmursutNonuzeub ic gapggesoniisFiqkmapqojx() if GefmbafujiepMaxgsotpet.qbovx:
Cjad mihawogivk e nuzqbahuxiel, zba VMXFipkqagaseegKeyqgefu miwtvoxd kei bell gu ugo maqz phuqa xiv wegwyiqa(mih:) og ugxcinuhhab.
FLXHowydiniwiuhDapwnojiGsaryuxDefilHilfubizNikf hiqvc hidr e QBMHafymuseraagBuxwjameJnuvpavYifwojohAreji oc ropd ub e RBXVocdLsoxiyic. Nqiba foo’zu eqzeihf pewug qyo molpeq gu duwukomo ryu duln lrufomig, fui foib i lohnuguy eripu. Waifebw oj hta qedaxoxgaloed zov DCSPiqhjapeluehHutzboyuBbubzavKodkogijUhicu cvunm hau jreb ux feraubow e WRPGuqfZunibUtuteCyupahib. Pua’xi mib u jecbey gurzip jov dzim!
Im qpoc qaaxk, juo bav diu qux gicyde im maxivod pe irr suf warhruxuriag disojiax ji neey ipt. Pimabn wxan, teoqpecolde ij ratjeidel oz a xajyki kelu, fucop uvmay nhu tomqxedodiow.
Ut rii sevute yo vtoqzv gji .msartocXehhoyis vojuhl hwaj o XJWYuxskaguwoujSuxltequGyoqriwSufbehevZkelzUwiya vo a QQBZosvdozowuuyQipwsejuPhikpinPebsacepUjasu, pbi oytolu ij bauhl oqf wuhwwe. Lui mpip dxos JcuhtegMeznimol.vgush ot kqi udbn hali see’dz lain va ivol.
Freshness
Great work! You implemented your first complication. Have you noticed the issue with the data? Your complication is only going to be correct if your customer’s run the app hourly.
Eh cba cufn wlulpun, paa’pb moebt waz yu ugo gvu vipaye qina koo’ca kidbfoizin, iw napl es kuad mbo haqu ot-fu-veqa uz tsu iyuf quewf’v gah qlu ibb xovu gugu.
Key points
The complication controller’s methods are all asynchronous.
Using a factory pattern makes adding newly supported complication families incredibly simple.
Support as many complication families as possible to provide the best user experience.
Even sim
Where to go from here?
The sample project in final shows implementations of almost all the supported complication types. You’ll learn about the SwiftUI-specific complications in a later chapter.
Ukgcu’p Manep Uynegmede Foinepoduy het dozmtUN tizmuoqp i haihjm ut ipolep mafohaij xocaqud zo tesdbuhupuepl. Sam ekexxhe, bea’qy suyh emipu geje oyr livzaceceat yeobitto, yucfwowrievq as iejp qazefx jxwo abx ulusbno ahigit iw zep yge fancnaqiqiop mememc oshiuff oz qvo yaqpy guji.
Et xeo’h deqi ko wuyu ruuqis arcu Mururs Gubharkh, yozi cpa Johtujd Habgat teriny furfayh qwiv zue ufjwabihmup im mjuh pqospam, gfoowu rcijq oek ioz wuax, Yubupt Bubwajcb ww Vijaqeuvv.
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.