Em um dos encontros recentes do grupo Seattle Xcoders Meetup, Curt Clifton, engenheiro de software do The Omni Group, descreveu como é desenvolver para o Apple Watch. Ele apresentou um modelo conceitual de watch app, comunicação de dados entre telefone e relógio e alguns desafios.
Modelo conceitual
A primeira coisa a ser considerada, diz Clifton, é que no WatchKit 1.0 seu código executa como uma extensão empacotada em um aplicativo para iPhone.
O relógio em si não executa nenhum código senão o da Apple, mas pode hospedar conteúdos como imagens e storyboards compilados. Imagens também podem ser geradas dinamicamente e enviadas ao relógio, que tem disponível para isso um cache de 20MB, mas que é lento e pouco confiável, diz Clifton.
O framework WatchKit é bem pequeno, observa Clifton e é constituído basicamente de classes Proxy para views (telas) no relógio. Além disso, essas classes na maioria dos casos apresentam apenas métodos setter, sem getters.
Opções de sincronismo
Uma vez que a extensão iOS executa em um processo diferente do aplicativo que o hospeda, sincronizar dados entre eles é vital. Por isso, Clifton revisa os diferentes mecanismos de sincronismo disponíveis:
- NSFileCoordinator: esta opção para coordenar a extensão com o aplicativo foi infelizmente descartada através de uma nota técnica da Apple;
- Grupos de direitos e padrões do usuário: muito fácil de configurar e usar, mas notifica caso ocorra alguma alteração;
- Base de dados CoreData/SQLite compartilhada: mecanismo bom o suficiente, diz Clifton;
- Seed File e callbacks: solução usada por Clifton no aplicativo de exemplo e que foi descrita mais detalhadamente por ele:
- O aplicativo hospedeiro escreve um "seed file" no aplicativo container compartilhado com, digamos, um envio de JSON;
- A extensão do relógio lê os dados contidos no seed file e então, quando estiver pronta para enviar de volta ao app-pai, chamará o método openParentApplication:reply: que consegue em background "acordar" o aplicativo-hospedeiro. O aplicativo pai receberá uma bloco de resposta que executará quando estiver pronto;
- o aplicativo hospedeiro pode atualizar os dados no seed file e então executar o método de resposta, que pode ser utilizada para passar o novo dado à extensão;
- A extensão do relógio não precisa mais ler o seed file, ela apenas atualiza em memória o dado recebido através do bloco de resposta.
A próxima parte da apresentação foi dedicada a uma revisão pelo código-fonte do aplicativo de exemplo e uma demonstração de como depurar no Xcode, que é um processo similar ao de se depurar um aplicativo de extensão iOS 8.
Desafios
A parte final da palestra é dedicada a discussão dos desafios que os desenvolvedores encontrarão:
- Conforme mencionamos, o WatchKit oferece apenas setters, assim um primeiro desafio é enviar comandos para controles não-ativos. Isso pode levar a inconsistência de dados e a forma de lidar com isso é ter cada classe controlando seu estado atual, seja ele ativo ou inativo. Essa estratégia é implementada no aplicativo de exemplo através de um conjunto de métodos _updateDisplay*;
- Frameworks compartilhados entre o aplicativo hospedeiro e a extensão para o relógio, dado que o framework será copiado em uma fase de cópia no Xcode;
- Auto-layout não é suportado e é substituído por grupos que se pode preencher da esquerda para a direita e de cima para baixo; pode adicionar grupos dentro de grupos e construir UIs complexas, mas é um modelo completamente diferente;
- Por último, não foi divulgado como será a interface de notificação do relógio, e ainda não está claro como lidar com notificações vindas do relógio.
O código do aplicativo de exemplo de Clifton está disponível no GitHub.