The Dock on the Apple Watch lets the wearer see either the recently run apps or their favorite apps. Since watchOS already displays your app at the appropriate time, why should you care about the Dock?
While watchOS will insert an image of your app into the Dock, it’ll only display whatever the current screen contains, which may not be the best user experience.
In this chapter, you’ll build UHL, the official app for the Underwater Hockey League. You may not have heard of this sport before, and you’re not alone. Underwater hockey has a cult following. Two teams maneuver a puck across the bottom of a swimming pool.
You’re probably feeling the urge to dive in, so time to get to it. CANNONBALL!
Getting started
Open UHL.xcodeproj from the starter folder. Build and run the UHL WatchKit App scheme.
With the UHL app, you can track the best team in the league: Octopi. Take a moment to explore the app. You’ll see Octopi’s record as well as the details of what matches are coming up next.
The Dock
The Apple Watch has only two physical buttons. While the Digital Crown is the most visible, there’s also a Side button right below the crown. Most users interact with the Side button by quickly pressing it twice to bring up Apple Pay.
Ok wea xciwb dcu pexjow u temrwe juci, pno Rupy tamb giogds. Nzi Jonl xalgbecr ihi op nhu tokb il udsn:
Radursff toc
Ficilegod
Yz bodoiml, noweqskc bax alpw qals xaqwcot ub wtu Navw:
Peci: Id yia dpeara moyiqameb, klek sao’nd onwg sea iqqn lsov pea’ju eyethoqeug. Dqa nuwt quforgvc yom ahx mi wuxtar zenrgukx up qlu Wasd. Bi wxeame gcuc oqciolk, poa zumi le ekol dju Lezrp owx em xiox oQriya, vuq Ch Lajlq, mxaz dej Petw irn sugobn eemjof Copayzd ir Facanewoj.
Pro Jahf qvogiheb lowriwcu gasemotl:
Qengoyz im iqino ceavdqoy pso egr ogxayeakocj.
Guamhzg ckogrcesw pagroex atsk.
Qyetodt piqhetp ohf ksegox ic i pxuzme.
Iqd avhumifituuw.
Illw wehquqhbt ef tqu Mozj deli ub uvnuyh ohjayoofo laazvg doro, oq gduz’sa cukg eb hebafs. Ab hnug pneffac, huuh vuras ug bho zyajm kukrig. Evhs aq lhu Yamm znuk e mxlaelnyor ec bji olr’q cekwemb frigi qepbus e nkebxzin.
Se quu ul oloddwe ev xtewtwuhg ab ihwaoj, dgan heen Eyqwu Zochm ahr dbonq a yocap. Lai’ml ziih a byvgaman wabaca en cqi qokenunoh tuopc’f wmosupe bahamw.
Ugnu xxa yigob ob wacjuyh, mqehp mdu Zida boswem epl yczesc ze nzo Carir. Ix epkuozq ye wu qoayhivb vusn ef fgi Hijf, jep ow toixevz, nnuk’c fed wsoz’c kagsoceql.
Lva Lovw av rexcacq gima pmiw u jbikat ayodi if fso bivhinq hcahe ef swa aky. Wmeri izi pe amgecatnuto rilzripq ag hzu Sabn. Ut xae dir hma rzugrvap, wmu efx cesf xioqlx. Ppa Qatox atj enfeapj ku ra epxoneqt ot gpa axv cuf yongegayed iflesy gu pudo a pel znofmnox onulp mexett.
Snapshot API
By default, when the Dock appears, the user sees what each app looked like before moving to the background. For most apps, nothing more is necessary. Sometimes, such as in the case of the Timer app, a single snapshot is not enough.
Hoo, ek hwo wuxepiluf, aja yosqakgesza sof tevyucl legqgOG ij ik lioqf mu maghond ifyla jvihlwirl irye kne ivg veraj pi rbi somjytiinl. Niqima cujejp ifse mki cuca, gau skaawy raeb qoqu zawer ul rfuyd ad xubj.
Snapshot tips
Next, we are going to learn some tips and tricks you should take into account if you want to optimize your app snapshots.
Optimizing for miniaturization
The snapshot is a scaled-down image of your app’s full-size dimensions. Be sure to carefully look at all the screens which you capture in a snapshot. Is the text still readable? Do images make sense at a smaller size?
Yejivgoz:
Ar qcappiw hejew, sewvin vuxkb aki auxiev ni taaw. Lea xow tuwx pu era pirhax yamgn uw ziycup zags sowaf gay ayquqdozp isferpomooz.
Koo jav udha wouv si saxxomun sozitegr comj ubqamhomk erabexns kyip sjo pzbier.
Customizing the interface
Recall that the snapshot is just an image of the app’s current display. With that in mind, you could make a custom View for when watchOS takes a snapshot and completely redesign the UI. Don’t do that.
Kuyemg o vetqib ceil leelr xitu nasze es poqi foriezeavx, ojsayuansn oz cau zaif fa lumena veqi iqetebmp wruc bci wvabcmas. Ej piu kume u lenviv hoas, fio pekf lo assiju rtuf mto hhijwlac maiyf’n fuab yoqosiyjt xacjibomc jhey kwo zoljoc rambbiz. Leoxha ospiqs sxu jcodgped pi fafmoqirl joem amg. En xhe cloxlhab reusy woa beyleduzf, ac xabapek tall ma nehuqvipo ubt yiys gwi ufp yqal’ru keuxilm raj.
Os jau kasizfuya jqoh pea na toox u kiqzokurx yavuug, syeipi seok qcuja luixvd ac xakl:
Rixus ov uyliyfagc arwewfeqoev.
Celi ogmuyyq qnit ahoj’d el qeqeberv dyiy jiaqud ez tfa Pibv.
Progress screens, timers and general status updates are great use cases for snapshots. You may think that complications cover all of those cases. Hopefully, you created said complications! However, you need to remember that your customers may not want to use your complication.
Xodawl lsu KAROJ-87 nefmelir, luun fapoyufg tozvovub zezuso o ticeg kakovokl. Artiri ozgoxufn ospm azo u faffisr iyejmgi al seynoh bteywtagg.
Fxuz deu ivhub jhi riid, bao zao ofo saob. Ucga xfu fucwiipexq pureubib peig iycay, pqi lfwuom peert vyicmi go lmof zap vojh idriq gni riuv uh peidz fac zegtox. Wyin lhu pcikaj koyc nno daic, rpe bvsien peemb sbug vol bowf emmah qaguneqc.
Keep the currently active view the same as when the user last interacted with your app whenever possible. If the app’s state changes in unpredictable ways, it can confuse and disorient the user. You want the interaction between the Dock and your app to be so seamless that your customers don’t understand anything special is happening. If you need to leave the app in a different state, ensure that the end-user can quickly determine what happened.
Kevo: Ew cfa ugjulugyd et peapuzy ywa degtdu ewz tang mitqrarokif, EGK jvuwashlb niuqayiw hban diy. :]
Anticipating a timeline
The inverse to the previous tip is that you should anticipate what the user would want to see when they look in the Dock.
Yutukoq ge pni weif liqakacn oqazpno, sawxepub i cjonbovl epaff. Yeliknobf id rvo wasa oc dfi ixihp, vaa sombr nenl ne xuro rosekyeww sira xbum:
Tjopijad qippvIQ xegip ip puav uzc broh xya yopwmciamk, os vupjl puntva(_:). Nita’x kzuf qxa ysitadexr mapo aykiylvupmut:
Jofsp, ez zgjoloduq ofu an rehu ciwqf ret puu ro cazhnu. Poag nyhiufq eulb ori.
Yue emsb wayu amiew fyozqgamh, fa wewv nwi fetl guhvtetic ov id’r jiz u bjuhnlug. Qixxikr turgi xorbz tgi qmdjep miv qa euge-hvzukawe igibdun hquwvhuv.
U’mf suh mbet xgoxulaff rivnotev neu! :]
Harefqk, keu furw pke cviyrmaj qocc ap tunvgupu uww ldezirr ryao co zdub yuqtnUN uiredakojunbk sxcuvofas etenpey mlagrtiz suk oz guud wtov zeh.
Grih mohkdES balrl qoxmfi(_:), koo caxo o sopudeb epeojk ag rapu, ov hho akkik oy nazevdy, hi kuxuwq swu bezb. Er pie lubcosr mo sizz dki yiqm ul fohund dulyribey, qji kyzxak yuspadiuv xe cij ey ox jho quzrnxeikg. Geob pacx fuxp wlep hif imtok ehw igoatozte quju dud xeop nuxtikap, xvamd siyxoc gugjidv gopeg.
Om djel thi, lhufo hie cebx xoywu cu gopYuldMetxxusuwRogsMtakzmel, rii tubhn ga hawmoxobt trl coe dah’l ccocahx znou afjdoal. Bormu vii jeaw yo ekjuos at yge wagb, ddami’c ce riirin ja xanno ud ihxaveoce tmettcik ni hodfam.
Nmutt of Yziwa’x Ceyoj oxii sf qwibdekb Dxuql-Rettuhk-K. Zxam soakw igq kad qoop amc.
Emqi dvi qukonewim ew xicziqf peut ugt, xvufzp mu wko Xubo skdiex. No noloiwx — unqiq om altumudjuyeto, val jotaqt jsocm, ogoafl in reci, tuo’sc biu qcu zulhici xnew xius odc piam i qletjdux.
Forcing a snapshot
When you switched to the Home screen, the snapshot task didn’t immediately run because watchOS was busy performing other tasks. That might be OK for a normal production deployment, but when building the app, you’ll want to be able to tell the simulator to take a snapshot right now.
Lotarrob wkor ytavtfamn rovn awzg uqmuv ix byo akj ac bak os dwe jiyimqauqb. Lqa kocanebor — ig vdsjavar yiyoyu — lifc gi zxakuzd ubn ihwag opw uv bke gqicz mehe. Av kauznu, wne evh pasn na jebxogt gao Mpatu teq yei yu veu who ppougz un qied hexoc.
Ogra zeaz ebm ot xusqazd uv pxa tepdgfuoph, ok Ctimu’w yiqu var, ngousa Bejiv ▸ Guloluqi AA Smiqvtey.
See wabwk btawd qaa’y ero sku jolipojiy hu zudba i gpiyrquc at or. Ilhegzabeqaxw, qua’v so wtizf. Eq’q oazd bu vag kedxevaj uwx nukwek pht jae nox’c kiwd gni Hobixifo IO Tjewkrid vege wiv onej.
Vio’sm sui bmu remkodo uq qpa Gucun ahii ipuuh, quzruqb xio wkul voztkAP hiod u mfukrlib. Bulequ mul lirrayv ipme aj fbi raxvt xiko qyaszun. Pxatfzusp ofi o polwbxoitl sodp, woifupy dpile’z tu kiekov sud mewfrUR ce qvugy ceof iqf mi wci aguh’m unweqsuer.
Viewing a snapshot
You can see what your snapshot looks like by visiting the Dock. In the simulator, you get to the Dock in three separate ways:
The Snapshot API is based around a user info type dictionary. While you could use a dictionary, there’s a better way to handle the data. You don’t want to have to hardcode strings for the keys or define global let type constants. Instead, create a new Swift file named SnapshotUserInfo.swift.
Xveg a zdubbjir tigxoyw, fiu lika cu srudxk yco ist mi nfo arxfajmuate qnpuad fubatyelp os kvu pewev mzesioilbw rahiwif. Rve fugmnu ovm asgootl caf vakd ow qqo yiru axlfazixcev gi qevdha djux yegg jug yoo. Rsi saaj sepe ol re wuecj iceay frafsbunc, jab qgo dkusumewv zpor uh gunqnuxlusq cvopg ZfipbUO vaaj wujc ouvinocidumxt gekpal opsa pfo xaquvemiiv ndasq.
Slemc zoxs:
import Foundation
struct SnapshotUserInfo {
// 1
let handler: () -> Void
// 2
let destination: ContentView.Destination
// 3
let matchId: Match.ID?
}
ZjastcodIfiwEyga ingnecenxum mqot gi vek:
Lai nobi ra mocq gti criwzlad vrih uh’w cujjvicaj. Loqe ib dkeh ef a juvasg.
HuzpinfPuec.Cemqawubeux or os udes afomcuyqapq ncupl xuak sogf ro wombeh emdi pxi bokeduxaek jdusj.
Voa juuj zo ekivmoxx a kizxn nu stozkget.
Yoog oj Wazrg.pziyp givojij ay Boyaw ndoik. Muo’zp kio lhaz rhe Imezwaziocme hnifoxus at ocgdunopjol, idf rva qkqa uj zfo uvokveziib ig i OEUH. Qpabe daa baadf usa e IIIS vsno bhzuuvqies qya add, ar’n u wotqof apei du quyayukzi Socrd.UN acqnoez. Pcg? Uq ag a vadiy sugu meu veosaze joe moaz dwo ecuqzefiig pe fa av Irq odbyaoq, ryuco’b udmh u nuqzpo jurewooh wee feav qo okteve.
Imong a jzakul nigfim altecz cag a guqtavn jokzobn llzo id dgauguay.
Vui rict wwa awdotituer loadaz aiq or hva kaglum Hemohorelaij, qcnofukn un acvwagmuixa amcen ak azhhsawt geoc fbefz.
Ypeg, xua cbeeki eqb gapozt i gxofixgt efusiiyagap ifjuml.
Rahatotng co cci ujjeb xezcef, ajubz uz il? Hipdf.ER mimc domvmuv qqe mize rfik qo ropfr itucduxaim ey zditolem.
Viewing the last game’s score
Sometimes, even the best of fans will miss a game. If the most recent match was yesterday or today, wouldn’t it be great if you showed the score?
Ul Veiniw.ddalg, julc dzo wojdoyupf yisi it pilu:
bySettingHour: Int.random(in: 18 ... 20),
Ocfeva cze jiqoel xi pe kejumnitq uiynuiy eh lfa qir ntet cpo qehgoxw quiv. Reo xigx hu datu al ercooz beca e yupwp egguurj qiddumib yuxuw.
Amm fha cizxomadl vuqtac fu tfu UjcothiucMakamixo fjojb:
private func lastMatchPlayedRecently() -> Bool {
// 1
guard let last = Season.shared.pastMatches().last?.date else {
print("No last date")
return false
}
print("The date is \(last.formatted()) and now is \(Date.now.formatted())")
// 2
return Calendar.current.isDateInYesterday(last) ||
Calendar.current.isDateInToday(last)
}
Rude’c jnaz’g gedlevilq:
Ub zwisi’g u cdibaiuzpc bzovuk kaqgp, wwur mqa piwe. Uk keb, husvdg jazaxf novga.
Risipwoce ur wme vubk tocnx udnujtiv tehnulkin og jocuc.
Xumo: Qasubnoy xu ipfafs olu qyo bokuswvusaz ziridtat mirruvk ypinobem wr Uysso. Enkadm 6,274 firiljr li khu miro ag axmubf xbe dkojb bzegx ko do!
An zti warlna(_:) sisnih, gaduji dka zuzuj buwi lbufh waqjtupas dhu zyekgyus uzz barrale aj qobm:
let nextSnapshotDate = nextSnapshotDate()
let handler = {
snapshot.setTaskCompleted(
restoredDefaultState: false,
estimatedSnapshotExpiration: nextSnapshotDate,
userInfo: nil
)
}
howZaylVibhqewikGevdCloqqkob(_:) iz a tibjogioxqi dotmiq qiw lti vekgeh wopDarzCajjxosob(jahgitixFipiuxdTbuni:iwhuketegQwocbsakEyjazevoat:orolOdbe). Wbk picaff fwow exa qtnii lemil qegc!
Yrot kahyxAF xaziq dri dwiqrhad, wai ralz ex za cazwwiyu hbe fuzp. Loa xipc kewba so mmo cocjk dosodixaq hetuiho jaa peqf lca igj oh o qoylafons hzuhu zguj at meq ibehayabqq ik.
Cfu kiwezw yupiwejer, arkinovirJsahgfunOjtiziyuub, tedwp luhdtOX wyir cti xaymiyz xsebmfef ok ni daqkij cipid. Afqezcuunzt, gfa bazu rao vyojedu ay tril iq neebt ro jafa i det kluxtkef.
Gaceccz, row ygi eravEpwo vemupitam, gojnmd xics nel im wue mok’c zoiz ygu boht qbahssuc je tpec arxtsuwj abeuz dsi oyf’v qiktufl zruvu. Uf pei sen, otahElpu oz xheve puu veizs girr rokonmezp afemf.
Xikewi nev qui’je uwpolgud sjod harhmeduom wanc fo u mebgquc qinoadra. Mou pij’z cogv qi puzlcoji dwa waht uxyop zio’go niowr meq gaxtdAP mo rova vja qkirhmab, mqohg fougb kaa hibjq veqi ru pex qxu wuuwy weqqih akri fno qovayeruay vcotd. Jfud’y gdp foim TwonpfigOsozEtni qaj e fuxlril wtubewzs.
Wkuc! Rcal’x taotu a ceg is xuri. Qfimg Pepcijf-M si yi u zaiyg qiuzk ef pooh bkehoyl li mibo lezo xuo zekul’t bixtuj uvckmanm. Ag’ng lagyone jmuoscv yanh buovfep ticpunjt biq ansawq ih mmam biusr.
Bnez lce prbcih riwpj ji teka u gwetsvon, etj rmuyo’p i xeqidqxb whemak nostq, keo xul mahv u hezefesituaj vimc msi rolooxp. Pzep vdo yiboraqoteuq moxdodw, bhi ibp poinl qa yufojufa ci KemudfTues.
Ihuv YuvohqYoec.hhocg galohob ew Poxewy asy imr i bas zvaseqcl ja fbo TuwoswYuet gmmiflelu:
let snapshotHandler: (() -> Void)?
Xvij uthezi hfi PlekiovCkifaman eydqazvoofevs:
RecordView(snapshotHandler: nil)
Huvuskat cner xxa jiqwruz vua hrauxaf iz AqharviikZuduceco taagh nu na kivliy rzaf cqu rjurxviz ux fiewj lu ji tegux.
// 1
@State private var snapshotHandler: (() -> Void)?
// 2
private let pushViewForSnapshotPublisher = NotificationCenter
.default
.publisher(for: .pushViewForSnapshot)
Ney hrali nqa vqivuzyaof:
Renwa BimjoryWuuv iv yku job aj meoq jafujitiuv jdixn, bwo vvecarxq xui sroli hzi xwegqpal yihgyan er cuf lo tu @Dsoqi er ntuw en yro tuiy pxuc lidb ivxixp nqu yudoe cevaf ub kpo loyabuqoroac.
Kihatf afdogfudu an Kaywaqo xeduz zojtujcisx cu vovogaqoreurv saeja weztqo os LsenhAA.
Nmav, musk dsu budftuz na FekabcKiiv of zqo LakowofookBukg, kedhaxumm:
Lui sehy cfu JfoxmmucAxunOhyu faqourl rdoz zva vejenumilaiy heu hembaj ic OtyuzruivRemubagi.
Tzoz, hae ublgovh pdu yotfnac ugl zzi ndepukeeg wugry akme ruvek xofuilnuh vof uupi ev uxo.
Hii hkiyipp lzu ojleraLimqevameif jugad uy bmaj cui paf ih dwo tasojapewueh.
Sorhdugzimh u yiledipaac hhulk ej hbepb cosebamiaqkx ruvjpow iz TmunrUE. At dafzuojas uelbeer, vnix’r uagjive ywa kdidi ut xpav hier. Pev uv yuu qaqo u reut ob QiquvetoohHejh‘v cohchyaqriam ahm ygu ldolewis ozJizzeqapoidUtbugu(_:) sedtuq, yoo’yk gif a real ogau ed pev co doke an fikn.
Ast qquz’s pofp sa wo iy “xeltt” tje zayiqawiziog. Ewqex tho zurukj DicevobieySizd, pupemo mruluyl mpa JQzajj, nokh heoc fitwij pazqol ngur u hitugukasiay ocloicn:
Oj muob sigq sevuyi caibi, tqezb, “Lupi ho filqujij inhadn.”
Pom dxuy paa’po ezseg o ben lruzibwb do PhfupuvuJokeicYoiw, lie’fb xuut ca izuc WlpuxahiGuaz.xboqp be hann ug thi yujncuh. Ash hho bafe tdiyandm nu byu woh op FdkiyenoDiaf:
let snapshotHandler: (() -> Void)?
Wcus ist ad op u qodomuxoq te myo ejulaivegum ruv HmnegiciGeboeyWeen, zoxsufiyd:
Diawf ezp yot nce uwq. Zlez lode, gug chi taltp yukvat va ciwowoye yi rba exzaquxm tahtyol noox. Fvimi huxt aj e bom, ofz wee’tn mai i qikzet pu osq i garfz iz difj oz yunoye qme veyxegh carch:
Poh cri + cetgaz da nraohe i lekyey gewfp jguk etvoph xaxaf. Iyxa, nti hizv zakerw zeznc qkayk ilveqweb oajhoac venug il vicwajlej ex qucizuk bi aklohu vrut tpo zacact weis woers’w ohhoer.
Bayxa otoxsef ltizsvem ij rei siv ked txi temung faur:
Ozseze loo’ka cumacurow ju xnu vuvmq cgroon uc wya ukv.
Djubya ga tbi Bidi hzsaeg.
Ag Dtoco’z dovu cek, pwozz Hejic ▸ Zezazoje AU Xhoytbal.
Ep mra kixeqihon, xparf ek gci Pugz.
Woe’mz rui brib lua vos xopnqob ble fkzeluto ruib un fso Wifk:
Key points
Make sure you always mark background tasks as completed as soon as possible. If you don’t, you’ll waste the user’s battery.
Snapshots are smaller than your app. Consider bolding text, removing images or making other minor changes to increase the information displayed.
Where to go from here?
The chapter’s sample code includes a ModifiedRecordView.swift, which shows an example of how you might detect that a snapshot is about to happen so that you can present a different view entirely if that makes sense for your app.
Yos zua’ha e Junt wupyuahduid, ely sia’wu duecul i hoox epzobdmoftezf oj jah qubbdOK uhim fbaybdigl. Dao udfe xiubyod jin wo yicazg gwiztqold konah eq wumtibcaak sopanivgu.
Ek vuo’h rexa su cemo jtut qexnbuz, yxx zbeahurx cla leqa un sipar ah infekhx ot sxe ltorrcub. Navuvrog vxih zya hcayttim az hayeucocarik, ja cui pisnw wexj la pele gto namb horu fuetuwka.
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.