Logo Apache Cordova

Share on FacebookTweet about this on TwitterShare on Google+

Vamos a crear una pequeña práctica con la que aprenderemos las características básicas de Cordova, manejar la API de para usar las características nativas del dispositivo y a crear una aplicación con una arquitectura óptima para móviles.

Objetivos

  • Usar diferentes estrategias para el almacenamiento local de datos.
  • Uso de las APIs de Cordova para Geolocalización, Contactos y Cámara.
  • Como manejar ciertos problemas específicos de móviles como los eventos táctiles, scrolling, estilos, transiciones entre páginas, etc.
  • Como construir una aplicación utilizando una arquitectura de una sola página (SPA – Single Page Application)
  • Como compilar y empaquetar (build) una aplicación de forma local usando la CLI de Cordova.

Requerimientos:

    • Conocimiento de html, JavaScript y jQuery.
    • Un movil o emulador y el SDK de una plataforma (iOS, Android, etc.) instalado en el equipo. De no estar instalado solo se podrá testear la aplicación vía navegador.
    • La práctica la he realizado con un sistema operativo Linux (Ubuntu 12.04). En principio se podría realizar también desde Windows o Mac

Referencias:

1. Crear un proyecto Cordova

  1. Asegúrate de tener una versión actualizada de Node.js instalada en tu equipo.
  2. Abre una terminal y ejecuta el siguiente comando para instalar cordova a nivel global (modificador -g):
  3. Colocate en el directorio donde quieras almacenar tus proyectos. Por ejemplo:
  4. Crea un proyecto llamado Practica:

    El primer parámetro es el directorio donde se guardará e proyecto. El segundo es un identificador para el proyecto con estructura de DNS inverso, el tercero es el nombre del proyecto y título que mostrará la aplicación. Puede ser útil poner el modificador -d para mostrar el progreso de creación del proyecto

  5. Entra en el directorio del proyecto:
  6. Añade las plataformas que quieras soportar:

    Ojo, necesitarás los sdk para añadir las plataformas y no siempre es posible: el de IOS solo va en Mac, el de Windows Phone en Windows :-(.

  7. Asegurate que estás en el directorio “practica” y añade estos plugins básicos a tu proyecto:

    Extraido de la documentación de los plugins:
    Plugin console:
    This plugin is meant to ensure that console.log() is as useful as it can be. If you are not unhappy with how console.log() works for you, then you probably don’t need this plugin.

    Plugin device:
    This plugin defines a global device object, which describes the device’s hardware and software.Although the object is in the global scope, it is not available until after the deviceready event.

  8. Examina la estructura de directorios creada en tu proyecto.

2. Hacer el build del proyecto Cordova

iOS

Nos hará falta el SDK de iOS instalado en el ordenador para poder hacer el build de nuestra aplicación, siguiendo los siguientes pasos:

El proyecto se genera en la carpeta workshop/platforms/ios. Si haces doble clic en Workshop.xcodeproj puedes abrir el proyecto en XCode,
y ejecutarlo en el emulador o en tu dispositivo

Puedes ejecutar también la aplicación en el emulador directamente desde la línea de comandos. Primero instala ios_sim:

Luego ejecuta la aplicación en el emulador iOS:

Android

Necesitas el SDK de Android instalado en tu ordenador.

Para generar el proyecto en la carpeta workshop/platforms/android y ejecutarlo en un dispositivo Android conectado a tu ordenador por USB:

Para generar el proyecto en la carpeta workshop/platforms/android y ejecutarlo en un emulador:

El propio parámetro emulate o run llevan intrínseco hacer un build. El build a su vez está compuesto de dos fases, prepare y compile, que se pueden hacer por separado.

android_emulate_install

3. Ficheros para la práctica

  1. Descarga y descomprime los ficheros para trabajar o clona este repositorio.

  2. Borra todos los contenidos de la carpeta practica/www con la excepción del fichero config.xml.

    En el fichero config.xml se guardan las características generales de la aplicación y configuraciones (preferences) como el color de fondo o si bloqueamos la orientación del dispositivo

  3. Copia los contenidos de cordova-tutorial/www en la carpeta de tu proyecto practica/www
  4. Si tienes un SDK instalado en tu sistema haz el build de tu aplicación según el punto anterior y ejecútala desde el móvil o el emulador. En caso contrario abre directamente el fichero index.html con un navegador
  5. Escribe unos pocos caracteres en la caja de búsqueda para buscar empleados por nombre. Posteriormente implementaremos enlaces a cada uno de los empleados

4. Elegir un método de almacenamiento

Los distintos métodos de almacenamiento están definidos mediante ficheros y clases independientes. La idea es que todas las clases presenten la misma interfaz de modo que utilizar uno u otro método de almacenamiento sea transparente para el desarrollo de la aplicación.

  • Almacenamiento en memoria (fichero memory-adapter.js)
  • Almacenamiento en remoto (fichero jsonp-adapter.js)
  • Almacenamiento mediante LocalStorage (fichero localstorage-adapter.js)
  • Almacenamiento en base de datos local (fichero websql-adapter.js)
  1. Abre cada uno de los ficheros anteriores para explorar cada uno de los métodos de almacenamiento.
  2. Prueba la aplicación con cada uno de los métodos de almacenamiento anteriores

La aplicación por defecto está configurada para trabajar con almacenamiento en memoria. Para cambiar el método de almacenamiento:

  • En el fichero index.html, cambia el fichero memory-adapter.js por el que corresponda: jsonp-adapter.js, localstorage-adapter.js, o websql-adapter.js.
  • En js/app.js, reemplaza la instanciación de MemoryAdapter con el que corresponda según el método de almacenamiento elegido: JSONPAdapter, LocalStorageAdapter, o WebSqlAdapter.
  • Prueba la aplicación

5. Uso de notificación nativa

  1. El típico alert de JavaScript puede ser algo rígido para tu aplicación PhoneGap que aparenta ser nativa. Puede ser que queramos personalizar la ventana de aviso mediante un título, un texto específico en el botón o incluso una función de callback. La función alert de JavaScript no nos lo va a permitir.
    Para hacer una llamada a la ventana de diálogo nativa deberemos añadir el plugin correspondiente:
  2. Al utilizar nuestra aplicación algo nativo, deberemos añadir la librería cordova.js:

    Esta instrucción hara que Cordova inserte la versión específica de Cordova a la plataforma en la que estemos desarrollando en tiempo de compilación. Es decir, el fichero cordova.js no debería estar presente en la carpeta www de nuestro proyecto.
  3. Por último deberemos hacer un override de la función window.alert() cuando ejecutemos nuestra aplicación en un dispositivo que disponga del objeto navigator.notification.alert(). Añadiremos el siguiente código en nuestra aplicación (fichero app.js, en el bloque de registro de eventos):
  4. Prueba a ejecutar la aplicación desde el dispositivo móvil o emulador y desde el navegador del PC. Observa que la notificación cambia en función del entorno.

6. Evita el retraso de 300ms en el clic

Si pulsas el botón de ayuda y según el dispositivo/emulador puedes notar cierto retraso hasta que aparece la ventana de diálogo.
Esto es debido a que el navegador puede esperar en torno a 300ms por si el usuario hace un doble clic. Para evitarlo podemos utilizar alguna librería de JavaScript como FastClick

  1. Añade el script en el fichero index.html:
  2. Registra FastClick en el fichero app.js. En la documentación de FastClick se explica como integrarlo, pero quizá lo más sencillo sea dentro de la función manejadora del evento deviceready que hemos utilizado en el paso anterior, añadiendo la siguiente instrucción:
  3. Comprueba desde el emulador o movil que ha desaparecido el retraso si hubiese. En principio bajo Chrome y al tener el viewport con user-scalable=no, no sería necesario.

7. Arquitectura SPA

Vamos a configurar ahora nuestra aplicación para que se ejecute toda nuestra aplicación desde una sola página. Es muy conveniente este tipo de diseño en aplicaciones móviles porque su funcionamiento será más fluido y pretendemos que la velocidad de ejecución sea lo más parecido a ejecutar código nativo.
Si no estás familiarizado con aplicaciones de una sola página, te recomiendo que eches un ojo a este post sobre diseño y arquitecturas SPA.

  1. En el fichero index.html borramos todo el contenido del body (salvo los scripts) ya que lo generaremos mediante JavaScript
  2. Definiremos una función que será la encargada de renderizar el home de nuestra aplicación, dentro de la sección de funciones locales del script app.js:
  3. Observa que hemos quitado el botón de ayuda y que el registro del evento keyup lo metemos dentro de la función renderHomeView, por lo que deberemos quitarlo de donde estaba anteriormente (sección registro de eventos). También quitaremos el manejador del botón de ayuda.
  4. Modificaremos la lógica de la aplicación, de modo que una vez que se inicialice el adaptador de datos se muestre la vista de la página inicial:

8. Elección de framework css

A la hora de mostrar nuestro html en pantalla es importante utilizar un framework css específico de móvil, es decir, diseñado para un renderizado rápido:

  1. Uso propiedades específicas de css para animaciones, que utilicen la GPU
  2. Evitar el uso de propiedades como box-shadow, border-radius, gradientes o text-align

Últimamente han salido muchos frameworks, como Ionic que viene “preparado” para funcionar con Angularjs y que se integra perfectamente con PhoneGap, Intel App Framework que viene preparado con un css específico para cada plataforma móvil, para simular más el aspecto nativo, y Topcoat de Adobe. Hay muchos más, utilizaremos este último.

9. Uso de templates: handlebars

Escribir código html desde JavaScript es propenso a errores (comillas simples en vez de dobles, alternar texto con variables…) y además poco legible.

Utilizaremos templates para desacoplar la definición de la interfaz de usuario (html) del código. Si no has usado nunca handlebars, echa un vistazo a la documentación oficial (es corta) y a un post de ejemplo de uso de handlebars y otro post de precompilación de handlebars.

  1. Vamos a crear dos templates, una para la página de inicio y otra para mostrar los elementos de la lista de futbolistas, que guardaremos en la carpeta templates.

    En la página de inicio y según la documentación de topcat.io necesitaremos los siguientes elementos:

    • Navigation bar
    • Search Input
    • List

    Plantilla para la página de inicio (fichero home.handlebars):

    Plantilla para la lista de futbolistas (fichero listaJugadores.handlebars):

  2. Precompilamos las plantillas:

  3. Cambiamos las funciones de app.js para que carguen el template:

  4. Copiamos el framework de topcoat dentro de nuestro proyecto. Podemos elegir entre un theme claro y otro oscuro.
  5. Cargamos también el script de handlebars (al precompilar, cogeremos el runtime) y los templates precompilados:
  6. Si probamos el resultado, vemos que se le puede dar un toque adicional de diseño. Debemos crear un fichero style.css que añadiremos a nuestro index.html:

    Contenido fichero style.css:

10. Crear una clase vista

Vamos a dar algo más de estructura a la aplicación, “adelgazando” el fichero app.js. Nos llevaremos toda la lógica de como crear las vistas a otro fichero-clase, HomeView.js, que encapsulará la lógica de creación y renderizado de la vista. Debemos pensar que puede haber muchas vistas, y de este modo, cada una de ellas estará en su propia clase, sin cargar en exceso el núcleo de nuestra aplicación, el fichero app.js.

  1. Creamos la clase HomeView
  2. El código será el siguiente:

  3. Eliminamos las funciones renderHomeView y encontrarPorNombre de app.js
  4. Cargamos el script de HomeView.js en nuestro index.html antes de cargar app.js
  5. Modificamos la función de inicialización de app.js para que renderice la vista de inicio mediante la clase HomeView recién creada:

11. Implementar scrolling nativo

Cuando la lista de futbolistas es mayor que la ventana del navegador, si nos desplazamos, toda la vista hace scrolling (incluido el header).
Para que el scroll se produzca solo en la lista de futbolistas:

  1. Crea una clase adicional en el fichero assets/css/styles.css con el siguiente contenido:
  2. Añade la clase scroller en el div de la lista de jugadores (plantilla home.handlebars)
  3. Por último, ¡no olvides hacer la precompilación del template antes de comprobar el resultado!

En IOS, puede que aún así el header también haga scroll. Deberemos configurar la siguiente línea en el fichero config.xml:

Podemos optar por soluciones más potentes con la ayuda de librerías como iScroll.

12. Enrutado de vistas

Vamos a crear otra vista en la que mostraremos los detalles de cada jugador. Al tener ahora nuestra aplicación más de una vista, habrá que implementar algún mecanismo de enrutado que determine si debemos mostrar la vista de inicio o la de detalle del jugador.

Implementamos la nueva vista

  1. Creamos nuestra nueva plantilla, mediante el fichero templates/jugador.handlebar:

  2. Precompilamos las plantillas al haber creado una nueva:
  3. Creamos la clase JugadorView con el siguiente contenido (fichero js/FutbolistaView.js):
  4. Cargamos el script FutbolistaView.js en el fichero index.html antes del script app.js

Implementamos el enrutado

La función de enrutado tendrá que ir en el fichero app.js.

  1. Creamos una variable con la expresión regular que utilizaremos para mostrar o no la vista de un jugador en concreto. La guardaremos en la sección de variables locales del fichero app.js:
  2. Definiremos un nuevo listener para cuando haya cambios en el hash de la url, dentro de la sección registro de eventos del fichero app.js
  3. En la sección de funciones locales, definiremos la función route, que se encargará de enrutar a la vista concreta.
  4. Cambiaremos la lógica de la inicialización del adaptador, para que llame a la función de enrutado (fichero app.js) para que cargue la vista que corresponda en función de la url, en vez de cargar siempre la de HomeView:
  5. He añadido varios varias líneas al fichero , para la nueva vista:
  6. Por último probamos que el enrutamiento funcione y se muestre la nueva vista.

13. Uso del API de localización

Vamos a mostrar las coordenadas (longitud y latitud) mediante una alerta. En una aplicación real, lo guardaríamos en una base de datos como parte de la información del futbolista y al visualizar la ficha mostraríamos los datos de localización en un mapa.
Para utilizar APIs deberíamos ver la doc de Cordova

  1. Añadimos el plugin de geolocalización a nuestro proyecto:
  2. Registramos en la función inicializar() de clase JugadorView un event listener para el evento clic en el elemento de la lista “Añadir Localización” (fichero js/JugadorView.js):
  3. Registramos también en la clase JugadorView el manejador de evento addLocation:

  4. Comprobamos su funcionamiento

14. Uso del API de contactos

Vamos a permitir añadir a cualquier futbolista a nuestra lista de contactos.

El código siguiente solo funciona al ejecutar la aplicación en un dispositivo como aplicación Cordova. No se puede probar desde un navegador en el PC.
Para utilizar APIs deberíamos ver la doc de Cordova

  1. Añadimos el plugin a nuestro proyecto:
  2. Registramos en la función inicializar() de clase JugadorView un event listener para el evento clic en el elemento de la lista “Añadir a Contactos” (fichero js/JugadorView.js):
  3. Registramos también en la clase JugadorView el manejador de evento addToContacts:

  4. Comprobamos su funcionamiento

15. Uso del API para la cámara de fotos

El código siguiente solo funciona al ejecutar la aplicación en un dispositivo como aplicación Cordova. No se puede probar desde un navegador en el PC.
No guardamos la foto de forma persistente, tan solo probamos la captura de una nueva foto.
Para utilizar APIs deberíamos ver la doc de Cordova

  1. Añadimos el plugin a nuestro proyecto:
  2. Registramos en la función inicializar() de clase JugadorView un event listener para el evento clic en el elemento de la lista “Hacer una foto nueva” (fichero js/JugadorView.js):
  3. Registramos también en la clase JugadorView el manejador de evento cambiarFoto:

  4. Comprobamos su funcionamiento

Leave a Reply

Your email address will not be published. Required fields are marked *