Aleksandar Vacić

Ti neki momenti, koji vrede.

Šta ima novo u watchOS 2

Pisao sam pre nekoliko meseci na Netokraciji o watch OS 1.0 a nešto kasnije na svom blogu sumirao muke i dao preporuke kako pisati watch aplikacije za taj OS.

WWDC 2015 je bio i prošao. Dve nedelje i dvadesetak sati video materijala kasnije, vreme je da sumiramo šta ima novo, šta je staro ukinuto a šta je (nažalost) preživelo.

Samostalne watch app

Namerno ih zovem samostalne (standalone) iako ih ceo ostali svet, uključujući i Apple, zove native. Čak i to samostalne je blago upitno ako se uzme u obzir da se 3rd party watch apps i dalje instaliraju tako što instaliraš iOS app a onda OS preuzme watch app bundle i prebaci ga na sat. Tek od tog momenta ta watchOS 2 app može raditi potpuno samostalno. No, semantika na stranu, da vidimo šta nam je ta samostalnost donela.

Iznenađujuće mnogo toga. Naime, u watchOS 2 aplikacije mogu da pristupaju manje više svim hardverskim senzorima (HR, network), da rade delimično u pozadini, poneke od njih mogu ostati u foregroundu čak i kada je ekran isključen. I najveće iznenađenje od svega — moguće je prijaviti se sistemu kao watch face complication.

Komplikacije

Očito je da su u Appleu dosta toga imali skoro spremno još ranije ali nije bilo dovoljno stabilno i stoga je izbačeno iz 1.0 verzije i prebačeno u watchOS 2.

To je najočiglednije na primeru jedne od primarnih korisničkih novosti: Time Travel. To vam omogućava da se putem Digital Crown-a šetate vremenski i u prošlost i u budućnost a sve što je prikazano na samom satu će prilagoditi svoj sadržaj za dati momenat. Tako će Kalendar prikazati vaš raspored ranije ili kasnije, vremenska prognoza će prikazati drugačiju temperaturu itd. Ovaj feature je već bio prisutan u watchOS 1, ali samo na watch faces koje nisu imale nikakve komplikacije sem vremena: Solar i Astronomy. Svi ostali su imali neke komplikacije ali nije bilo Time Travela.

Očigledno da taj interni API – da watchOS ima na raspologanju potreban timeline podataka – nije bio dovršen na vreme za svaku od komplikacija unutar sistemskih aplikacija. Gotovo niko nije očekivao da će 3rd party apps dobiti mogućnost da privire na watch face pre naredne godine no eto lepog iznenađenja.

Ono što vi sada kao developer treba da odlučite jeste da li ima smisla da se vaša app uopšte tu pojavi. Za moju Run 5k app nisam siguran da ima mnogo smisla. Mogu da exportujem timeline podataka prethodnih trčanja, pa da se prikazuje trenutno vreme trčanja u nekom momentu u prošlosti, recimo u 15:42 sam bio na 1.38km…sem da pokažem da eto to znam da uradim, prilično je besmisleno potrošiti jedan od 3-4 raspoloživih slotova na ovako nebitnu informaciju.

Razmislite sami. Primeri koje je Apple predstavio što na keynoteu ili kasnije na samim dev prezentacijama su dovoljno ilustrativni. Vrlo je malo aplikacija koje ima smisla uopšte postaviti na watch face. Za mnogo više njih ima smisla kreirati dobar Glance.

Nezavisnost rada

Samostalnost watch aplikacija znači da sada watch app može da ima svoj lokalni (na satu) storage. A to znači da ćete vi, kao korisnik, mnogo manje gledati u loading indikator jer app sada može na satu imati svoje stanje umesto da ga pri svakom startovanju dohvata za telefona.

U mom slučaju, Run 5k će sada trenutno prikazati next/last run stanje, jer ću ga nakon svakog završenog trčanja poslati sa telefona na sat. Čak i u slučaju da se odradi neko trčanje u međuvremenu na telefonu dok je sat off ili van dometa, ta informacija će se odmah po uključivanju sata preneti sa telefona.

Za to je odgovoran potpuno novi Watch Conectivity framework.

Komunikacija

Oho, hoo, yes!

To je otprilike bila moja reakcija kada sam video Watch Connectivity. Kako se Run 5k zasniva na tome da od telefona dobija sve potrebne informacije za prikaz, Apple je sa WC-om (eh nesrećne li skraćenice) potpuno izbacio potrebu da koristim MMWormhole i Darwin Notifications za transfer tih podataka.

Background transfer tipa Application Context je tačno ono što mi treba da podatke o trčanju baziranom na GPS-u kontinuirano šaljem sa telefona na sat. Ja već sada imam ceo set podataka koji opisuje stanje trkačke sesije u datoj sekundi kao NSDictionary. Sada taj objekat svaki put kada išta promenim — a tu ima jedno 30-tak podataka — prosto pošaljem WC-u a on ne pravi vozić svih tih pojedinačnih slanja već uvek pregazi stare podatke novim te watch app vidi samo jedan set podataka – onaj aktuelni. Prosto savršeno.

Upravo taj tipa transfera je ono što se brine o tome da moja watch app uvek ima aktuelni next/last run info. iOS app će putem updateApplicationContext:error: metoda proslediti svoj poslednji aktuelni set podataka i WC na telefonu će čuvati taj set podataka do momenta kada sat ne bude dostupan. Na prijemnoj strani, WC na satu će primiti taj set podataka i čuvati ga do momenta dok moja app ne bude startovana i onda ga odmah isporučiti, tako da watch app to ima na raspolaganju pre nego willActivate dođe na red.

Za situacije u kojima vam baš treba da imate kompletan log svake promene, WC nudi drugi tip background transfera: transferUserInfo:. Tu takođe šaljete NSDictionary a watch app dobija niz koji sadrži svaku pojedinačnu promenu.

Ovaj API radi na identičan način u oba smera a napisan je tako da je jedan smer nezavisan od drugog. Pa možete imati jedan set koji putuje od sata ka telefonu i potpuno drugi set podataka koji ide od telefona ka satu. I sve to se prenosi na energetski najefikasniji način u momentima kada WatchKit proceni da je najbolje.

Ostaje da se u praksi testira koliko je to često i pouzdano ali iskreno ne očekujem neke posebne probleme. Ako ih i kojim slučajem bude, imamo…

Direktna (interaktivna) komunikacija

U 1.x imali smo mogućnost da asinhrono pitamo iOS app nešto i sačekamo da u nekom momentu stigne odgovor, putem openParentApplication:reply: metoda.

U watchOS 2 taj metod je ukinut i zamenjen sa sendMessage:replyHandler:errorHandler:. Da bi to radilo, watch app mora biti isključivo u foregroundu dok iOS app može biti u backgroundu. Još bolje, iOS app uopšte ne mora biti startovana — ako stigne ovaj poziv iOS će je startovati u backgroundu i proslediti poruku. Savršeno za moj slučaj gde sa sata startujem trčanje na telefonu.

U obrnutom smeru, watch app mora biti u foregroundu da bi poziv radio. WatchOS 2 neće startovati samu app automatski. Tačnije, neće uopšte stići zato što WC neće ni poslati metod ako sama watch app već nije reachable, što su dva od više različitih novih property-ja nad WCSession defaultSession. Ovaj singleton je vaš novi najbolji watchOS prijatelj.

Kad smo već kod sesija, za aplikacije koje koriste HealthKit — kao što je Run 5k — watchOS 2 ima posebno lepu novost u vidu HKWorkoutSession. Kada to startujete, vaša app će ostati u foregroundu čak i kada se ekran isključi. Praktično sve vreme dok je ta sesija aktivna app se ponaša kao da je sve vreme vidljiva na ekranu. To je savršena stvar za sve fitness app jer nas stavlja na isti nivo mogućnosti koje ima i Appleova Workout app.

Samostalno, ali stvarno

Workout app može da radi i bez telefona, koristeći zamaskirani CoreMotion na satu i HR senzor da meri razdaljinu, brzinu i sve te lepote. Sa ovim jednim API-jem Apple je omogućio da se naše aplikacije mogu koristiti na isti način.

To znači da sada na trčanje možete otići samo sa satom. U teoriji - ostaje da se tokom leta to sve testira u praksi. Dodatno pitanje je kako onda kasnije podatke o tom trčanju (ili više njih) proslediti aplikaciji na telefonu.

Tu na scenu stupa treći tip background transfera koji sam namerno izostavio da pomenem ranije: file transfer. Koristeći sličan API kao za user info, možete bilo kakve fajlove pripremiti i predati WC frameworku a on će ih jedan po jedan preneti na telefon, čim se iPhone pojavi u dometu.

Sa korisničke strane to će najverovatnije biti potpuno transparentno. Dođete sa trčanja nazad u svoj stan, skinete sat i spustite ga negde u kući, vrlo verovatno na istoj wifi mreži ili čak u BT dometu do iPhonea. Dok se osvežite i presvučete, sve je to već preneto i pri prvom sledećem startovanju iOS app preuzme fajl(ove) i importuje podatke. Milina jedna.

Layout

Ono što je (na žalost) ostalo isto jeste način na koji se kreira UI. Apple je omogućio da se još neki parametri UI-a menjaju kroz kod, ima i novi animation API koji omogućava da skoro sve možete da animirate i zaista kreirate dopadljiv UI.

Međutim, sve je to šarena laža. Ako sam ranije watchOS layout engine uporedio sa HTML-om 2, ovo sada je otprilike isto to, s tim što se pojavio i Javascript pa eto možete koješta mrdati tamo vamo, menjati providnost i veličinu itd.

Pravi UI API je i dalje dostupan samo Appleu i nekolicini mahera koji su već uspeli da dovoljno čačnu SDK gde treba i da onda prave…pa čuda. Pokrenuli su Kanabalt i Flappy Bird na satu, animirali 3D tekst koristeći SceneKit a jedan ludak je uspeo da prekompajlira i pokrene emulator Mac System 7.5. Ludilo. Verujem da Apple ima razloge zašto ovo nije dato svima nama na raspolaganje; najverovatnije standardna boljka zvana battery life.

No, ne vredi se mnogo žaliti. I onomad smo sa onako jadnim Javascriptom svašta lepo pravili, pa ćemo se snaći i sa ovim.

Komunikacioni deo je prava zvezda watchOS 2 i sasvim dovoljan da kažem da je ova nova generacija watchOS-a za red veličine bolja od inicijalne verzije. Vidimo se na App Storeu, tamo na jesen.