Tidligere denne uken hadde mobilteamet hackday, hvor alle i teamet fikk bruke en arbeidsdag på å eksperimentere med ny teknologi. Jeg har lekt med Apples WatchKit.
I dag, 24. april, lanseres Apple Watch i de delene av verden Apple mener er verdige. Her på berget må vi nok vente enda en stund før de dukker opp i butikkene, en endelig lanseringsdato har såvidt meg bekjent ikke blitt satt ennå. Salgstallene så langt i de markedene er høye til å være smartklokker, men sett i forhold til salgstall for telefoner og nettbrett er det enn så lenge et nisjeprodukt. Det er dermed usikkert når, hvorvidt og hvor mye vi kan utvikle større prosjekter for Apple Watch så lenge det finnes andre, viktigere områder for oss å fokusere ressursene våre på.
Som utvikler er det spennende å kaste seg over nye teknologier. Dette gir anledning til å få både nye muligheter og nye begrensninger man må løse problemer for. Dette gjelder også WatchKit, navnet på utviklingsmodulen for Apple Watch. Samtidig som det er en kikk inn i framtiden føles det på mange måter som å gå et par skritt tilbake, og det er tydelig at utviklerverktøyene fortsatt ikke er modne. Xcode kræsjer mange ganger daglig, simulatoren fryser støtt og stadig, og mange steg i utviklingsflyten virker litt lite gjennomtenkte.

Mål for dagen
Ettersom vi kun hadde én dag på oss, trengte jeg et enkelt prosjekt med et fokusert bruksområde for raskt å komme i gang med å lage noe nyttig. Valget falt på P3-appen, en app som jeg også tidligere har brukt som prøveklut for nye teknologier. Med sitt enkle UI med få funksjoner og lite informasjon som vises er det enkelt å tenke seg hvordan en klokkeapp skal se ut. I sitt aller enkleste brukerscenario ønsker man å se hva som spilles på radio akkurat nå, og å starte eller pause avspillingen. Ingen pushmeldinger, et par linjer metadata og én knapp. Easy peasy.

Alle som er kjent med Interface Builder, Xcodes editor for UI, har blitt vant til å kunne plassere elementer hvor man vil og ha uendelig mange måter å justere hvordan de ligger i forhold til hverandre. I WatchKit er det ikke helt slik. Her må man velge horisontal eller vertikal layout, elementer kan ikke ligge over hverandre, og man har ingen mulighet til å justere plasseringen på pixel-nivå. Man kan legge inn spacere for å justere plassering, men den graden av kontroll og muligheter man før hadde må man bare gi opp. I tillegg må forholde seg til ulike typer visninger, eller interfaces som de omtales i Xcode.
Bygge opp visningene
Hovedappens interface har få begrensinger annet enn at man må forholde seg til UI-elementer kun fra WatchKit. Dette er elementer som ligner, men ikke er de samme som, de som finnes i UIKit. UIKit er rammeverket som brukes for å utvikle ordinære iOS-apper. Som i UIKit har man har knapper, labels, tabeller og bilder, men de er ikke arvemessig i slekt med sine motparter og svarer ikke på de samme metodekallene som man er vant til. Tabeller har ingen delegate, men cellene får hver sin egen controller-klasse som tar seg av populering av data. Labels oppfører seg som en blanding av labels og tekstfelt.
Velkjente UIView har blitt erstattet av WKInterfaceGroup som container av innhold, der man som tidligere beskrevet kun har mulighet til å legge ting i rekke, enten horisontalt eller vertikalt. Grupper kan legges inni hverandre, sånn at man får plassert ting nokså greit der man vil, men innhold kan ikke gå over flere grupper eller ligge lagvis med helt eller delvis gjennomsiktighet gjennom lagene.
En annen hovedkategori av app-grensesnitt er såkalte glance-interfaces. Dette er en hurtigvisning av appens tilstand, og er laget slik at man kan swipe sidelengs gjennom alle kjørende apps på klokken og umiddelbart få en kjapp visning av den mest relevante informasjonen fra hver app.
I et glance kan man ikke ha noen elementer som man kan interagere med, så ingen knapper, slidere eller tabeller. I tillegg er man låst til en layout der man har en gruppe på toppen, et mellomrom og en gruppe på bunnen. Innenfor disse kan man legge opp undergrupper hvordan man vil, men man får ikke endre på den grunnleggende strukturen. Den øverste gruppen låst til å dekke mesteparten, men irriterende nok ikke hele bredden av skjermen. Med litt filing fikk jeg plass til det viktigste av informasjon innenfor disse rammene, hva du hører på akkurat nå og hvor lenge det er igjen av programmet.


For apper som skal vise pushmeldinger finnes det ytterligere et interface med sine regler man må forholde seg til. Notification-interfacet har en applogo, som denne gangen skal være trill rund, et felt under som viser appens navn der du kan endre bakgrunnsfarge og lite annet, og litt plass til å vise en melding. På bunnen får man automatisk en dismiss-knapp, om man ønsker flere knapper kan man spesifisere dette i selve meldingen man sender til klokken. Ellers er begrensningene de samme som for glances, ingen elementer man kan trykke på eller gjøre noe annet med. Ergo ingen mulighet til å spesifisere opp knapper i Interface Builder, kun i meldingsteksten. Pussig.



Hente og vise informasjon
Når det kommer til kommunikasjon mellom klokka og telefonen endte jeg opp med å bruke et sett med metoder som heter
+ (BOOL) openParentApplication: (NSDictionary *) userInfo reply: (void (^) (NSDictionary *replyInfo, NSError *error)) reply
i WKInterfaceController og dens motsvar i moderappens AppDelegate,
- (void) application: (UIApplication *) application handleWatchKitExtensionRequest: (NSDictionary *) userInfo reply: (void (^) (NSDictionary *replyInfo)) reply
De sender og mottar NSDictionary, tilsvarende Map eller key-value-objekter i andre språk. Det er dermed så generelt at man i prinsippet kan gjøre det man vil, jeg endte opp med å ha et stringobjekt med nøkkel «action», der jeg spesifiserte operasjonen jeg ønsket, og et objekt jeg kalte «args», der jeg la ved alle argumentene som trengtes for den ønskede operasjonen. På den måten fikk jeg fort opp et halvveis definert og ryddig grensesnitt mellom klokke og telefon. Legg på et minimum av feilhåndtering og nullsjekker, så har man en enkel måte å hente ut nesten hva man ønsker. I dictionaryet kan man også legge ved bilder, enkodet som NSData, noe som kan være greit da klokkens mulighet til å gjøre grafikkoperasjoner er alvorlig begrenset.
I mitt tilfelle har jeg definert opp et par grunnleggende operasjoner:
-togglePlayPause, som sender melding til telefonen om at bruker har trykket på knappen og at sendingen skal pauses om den spiller, eller startes hvis den er pauset. Denne returnerer den nye tilstanden til spilleren, om den spiller eller er pauset, og bildet av en knapp i riktig tilstand lagt over logoen på kanalen som spiller.
-getPlayPause, som kun henter den samme informasjonen som over uten å endre på spillerens tilstand.
-metadataUpdate, som henter informasjon om hva som spilles nå, hvor langt programmet har kommet, og ca når metadatene trenger å oppdateres neste gang.


Med disse operasjonene kunne jeg enkelt populere opp grensesnittene med metadata, både for glance og inne i appen. Det endelige resultatet synes jeg selv ble ganske OK, for en dags arbeid med et rammeverk jeg ikke før har rørt. Noe opprydding og feilretting gjenstår før det er klart for publikum, så om det skal ut må jeg antakelig snike meg til en liten hackday til. Kanskje jeg til og med skal spandere på meg at en designer får se litt på appen sånn at den ikke bare er designet etter innfallsmetoden av en ingeniør.


Oppsummering
Alt i alt var det en spennende dag der jeg lærte mye. Det er helt tydelig at dette er første iterasjon av en ny produktkategori, en del ting var uvant og mye føles ikke helt ferdig og klart for utvikling på større skala.
Knytningen til telefonen er både en velsignelse og en hemsko, på den ene siden er det fint å delegere tyngre operasjoner, som manipulasjon av grafikk samt henting av data fra server og parsing av dette. På den andre siden virker det som Apple med hensikt har begrenset mulighetene for hva man får lov til i en sånn grad at alle apper som kommer ut til en viss grad kommer til å se like ut og gjøre nesten det samme. Men dette er kanskje akkurat det de ønsker nå i første omgang. Etterhvert som tiden går kommer nok utviklingsverktøyene til å modnes, utviklingsmulighetene økes og vi får en større forståelse for hva vi egentlig skal bruke en slik dings til.