Back-End

23 jan, 2015

Testando aplicações Phonegap/Cordova muito rapidamente no dispositivo (com o framework ionic)

Publicidade

Normalmente, quando trabalhamos com aplicativos Phonegap/Cordova, fazemos isso em duas fases. Primeiro desenvolvemos o aplicativo localmente, usando o nosso browser. Essa é a fase “rápida”. Nós mudamos alguma coisa dentro do nosso código, então recarregamos nosso navegador e vemos o resultado. Ele não é diferente de um processo de desenvolvimento web “tradicional”. Normalmente, eu uso o framework ionic. Ionic é excelente e também nos fornece uma boa ferramenta para executar um servidor local. A gente só digita:

ionic serve

E o ionic inicia um servidor local na porta 8100 com nosso aplicativo Cordova, pronto para testar o navegador (ele também abre o navegador). Essa não é a parte legal. O Ionic também inicia um servidor de recarga ao vivo em http://0.0.0.0:35729 e acrescenta o seguinte trecho no final de nosso index.html:

<script type="text/javascript">//<![CDATA[
document.write('<script src="' + (location.protocol || 'http:') + '//' + (location.hostname || 'localhost') + ':35729/livereload.js?snipver=1" type="text/javascript"><\/script>')
//]]></script>

Com esse trecho, o nosso aplicativo será recarregado quando adicionarmos/removermos algo em nossa árvore de arquivos (ele executa um monitoramento de sistema de arquivos no background).

Mas, como eu disse antes, é a fase “rápida” e, mais cedo ou mais tarde, teremos que executar o aplicativo no dispositivo real. OK, temos emuladores, mas eles são horríveis. O emulador Android é incrivelmente lento. O iOS é mais rápido, mas precisamos reimplementar o aplicativo em cada mudança. Por exemplo quando corrigimos um erro bobo que precisamos para executar o seguinte comando para ver o aplicativo em execução no dispositivo:

cordova run android --device

E isso leva tempo (cerca de 10 segundos). Passamos da fase “rápida” para uma “leeeenta”. Isso significa que tentei evitar essa fase até que não houvesse nenhuma solução.

Se não usar plugins, você pode deixar essa fase “lenta” para o fim, apenas para ver o comportamento do dispositivo e corrigir as personalizações, mas se usarmos plugins (plugin de câmera, notificações push ou coisas assim) que realmente é necessário testar no dispositivo real, esse tipo de coisa não funciona no navegador ou em um emulador.

Essa fase “lenta” me deixou louco, então eu comecei a pensar um pouco sobre isso. Um app Cordova tem duas partes. Uma nativa (código Java no Android e Objective-C no iOS) e a parte html/js. Nós precisamos dizer para o nosso aplicativo Cordova onde está o index.html inicial. Costumamos fazer isso em config.xml

<content src="index.html" />

Mas podemos mudar esse arquivo inicial e usar um remoto. Essa é a forma de criar um app “nativo” a partir de um aplicativo de web existente.

<content src="index.html" />

De acordo com isso, podemos iniciar um servidor local em nosso host e usar esse servidor da Web local, mesmo em nossa LAN (se o nosso dispositivo Android/iOS for a LAN, é claro)

<content src="http://192.168.1.1:8100/index.html" />

Mas o que acontece com os plugins? Os plugins precisam do arquivo cordova.js, e esse arquivo não está na pasta www. Esse arquivo é gerado quando nós construímos o aplicativo para uma plataforma específica

platforms/android/assets/www/cordova.js

Então, a ideia é:

  • Execute um servidor local com o servidor ionic.
  • Habilite o observador fs para reiniciar o aplicativo quando mudamos um arquivo no sistema de arquivos (o servidor ionic faz isso por padrão).
  • Crie o aplicativo e instale-o no dispositivo real.
  • Utilize o nosso servidor local para servir arquivos estáticos em vez de construir novamente o aplicativo a cada mudança.

Com essa abordagem, só precisamos fazer deploy do aplicativo para o dispositivo real quando quisermos adicionar/remover um plugin. Se não mudarmos nada nos arquivos estáticos (html, js, css), nosso aplicativo será recarregado automaticamente. A fase “lenta” transforma-se em uma fase “rápida”.

Como podemos fazer isso? É fácil. Neste exemplo, eu suponho que nós estamos usando um dispositivo Android. Se usarmos no iPhone, só precisamos mudar “Adroid” para “iOS”.

Antes de qualquer coisa, precisamos preparar o nosso index.html para permitir que o auto-recarregamento. “ionic serve” faz isso automaticamente, mas ele pensa que nós vamos usá-lo com o seu navegador host, não com o dispositivo “real”. Nós podemos mudá-lo manualmente adicionando ao nosso index.html (este trecho supõe que seu host seja 192.168.1.1; se for outro, utiliza o seu endereço IP local):

<script type="text/javascript">//<![CDATA[
document.write('<script src="http://192.168.1.1:35729/livereload.js?snipver=1" type="text/javascript"><\/script>')
//]]></script>

Agora vamos mudar o nosso config.xml para usar nosso servidor local em vez de arquivos do dispositivo:

<!--<content src="index.html" />-->
<content src="http://192.168.1.105:8100/index.html" />

Agora precisamos fazer deploy do aplicativo para o nosso dispositivo:

cordova run android --device

Cada vez que adicionamos/removemos um plugin, precisamos fazer o deploy novamente no dispositivo. Mas precisamos ter em mente que o nosso dispositivo usará o cordova.js do nosso servidor local, e não a partir do seu sistema de arquivos. “cordova run android-device” irá gerar o arquivo para a plataforma e implementá-lo no dispositivo real, mas, como nós vamos usar esse arquivo do nosso servidor local (em www), é preciso criar um conjunto de links simbólicos em nossa pasta www.

(Eu tenho um arquivo setUp.sh com esses comandos)

cd www
ln -s ../platforms/android/assets/www/cordova.js
ln -s ../platforms/android/assets/www/cordova_plugins.js
ln -s ../platforms/android/assets/www/plugins
cd ..

Agora pode iniciar o servidor do aplicativo no nosso host com:

ionic serve --nobrowser

perceber que estamos usando -nobrowser. Estamos usando esse parâmetro para a não abrir o nosso navegador local. Nós vamos usar de dispositivo um Webkit Cordova, e também se abrirmos o nosso navegador ele irá travar porque cordova.js está presente agora e o nosso host local não é um dispositivo real.

Cada vez que precisamos reimplantar o aplicativo para o dispositivo (novo plugin por exemplo) precisamos nos lembrar de encerrar os links simbólicos e reimplementar.

(Eu tenho um arquivo com estes comandos tearDown.sh)

rm www/cordova.js
rm www/cordova_plugins.js
rm -Rf www/plugins

E isso é tudo. Embora esse pequeno truque ainda possa parecer algo difícil, precisamos de menos de um minuto para configurar o ambiente e vamos salvar milhares de segundos no processo de desenvolvimento. Trabalhando um pouco, podemos automatizar esse processo e transformá-lo em uma operação trivial, mas pelo menos agora eu me sinto muito confortável.

É claro que você precisa se lembrar de limpar o projeto quando terminar e usar arquivos do dispositivo. Então, precisamos remover o trecho de auto-recarregamento no index.html, remover links simbólicos e restaurar config.xml.

ATUALIZAÇÃO:

O framework ionic agora vem com um recurso inovador. Basta seguir as instruções explicadas aqui.

***

Texto traduzido com autorização do autor pela Redação iMasters. Original disponível em http://gonzalo123.com/2014/07/21/testing-phonegapcordova-applications-fast-as-hell-in-the-device-with-ionic-framework/