Aplicaciones para iPhone con jQTouch offline
Publicado el 04/06/2010 en Programación por Jose M. Carbonell
Ingeniero de sistemas y apasionado de Ruby on Rails, desarrollo web y metodologías ágiles. Uno de los primeros en utilizar Ruby on Rails Rails en España.
En un artículo anterior mostré como hacer una aplicación sencilla para el iPhone usando la librería jQTouch.
Desarrolla aplicaciones para iPhone con jQTouch
La aplicación desarrollada en dicho artículo consiste en un sencillo cliente de twitter que permite obtener los últimos tweets de la cuenta de TheProc.es y de cualquier otra utilizando la API pública de twitter.
También mostré como añadir nuestra aplicación web desde el navegador Safari Mobile a la pantalla principal junto con las demás aplicaciones. De esta forma la aplicación web se adapta perfectamente y a todas luces parece una aplicación nativa.
Sin embargo, sigue siendo una aplicación web, con lo que cada vez que la ejecutemos desde el iPhone necesitará acceder al servidor para descargar los archivos necesarios, empezando con el fichero index.html, continuando con hojas de estilo, scripts e imágenes.
Esto implica, primero, que siempre necesitaremos estar conectados para que descargar los archivos y que se inicie la aplicación y, segundo, que consumiremos transferencia de datos cada vez para descargar los mismos archivos una y otra vez.
En caso de no tener conexión no podremos ejecutar la aplicación:
Podemos evitar este problema utilizando las capacidades de HTML5 para almacenamiento offline soportadas por Safari Mobile.
Nota: La aplicación de ejemplo no podrá funcionar totalmente offline, ya que necesita conexión a internet para obtener el listado de tweets, sin embargo, podríamos hacer un gestor de listas ToDo totalmente funcional offline o cualquier otro tipo de aplicación.
El manifiesto
Lo primero es crear un archivo que contendrá una lista con todos los archivos necesarios por la aplicación. Estos archivos serán cacheados y estarán disponibles offline. Es lo que se conoce como fichero de manifiesto y suele tener la extensión .manifest.
Este archivo tendrá el siguiente aspecto:
CACHE MANIFEST
# version 1
CACHE:
# recursos accesibles offline
NETWORK:
# recursos accesibles online
FALLBACK:
# archivo utilizado cuando se intente acceder a un fichero no cacheado y no haya red
Los ficheros de manifiesto empiezan con la línea: CACHE MANIFEST y agrupa 3 secciones: CACHE, con un listado de los archivos que queremos hacer accesibles offline, NETWORK un listado de los recursos que queremos hacer disponibles online, y por último FALLBACK, que será la página mostrada en caso de intentar acceder a un elemento no cacheado en modo online. También puede contener comentarios mediante el símbolo #.
Es importante tener en cuenta que, como en nuestro caso, si la aplicación necesita recursos externos, estos no estarán disponibles si no están especificados en las sección NETWORK, incluso aunque tengamos acceso a internet.
A este fichero se hace referencia en la etiqueta html de la siguiente forma:
<!doctype html>
<html manifest="jqtouch.manifest">
<head>
</head>
<body>
</body>
</html>
Un ejemplo del fichero en la aplicación de demo:
CACHE MANIFEST
# version 1
CACHE:
index.html
apple-touch-icon.png
jqt_startup.png
jquery/jquery-1.4.2.js
jqtouch/jqtouch.min.css
jqtouch/jqtouch.min.js
themes/jqt/img/back_button.png
themes/jqt/img/back_button_clicked.png
themes/jqt/img/button.png
themes/jqt/img/button_clicked.png
themes/jqt/img/chevron.png
themes/jqt/img/chevron_circle.png
themes/jqt/img/grayButton.png
themes/jqt/img/loading.gif
themes/jqt/img/on_off.png
themes/jqt/img/rowhead.png
themes/jqt/img/toggle.png
themes/jqt/img/toggleOn.png
themes/jqt/img/toolbar.png
themes/jqt/img/whiteButton.png
themes/jqt/theme.min.css
NETWORK:
*
http://api.twitter.com/status/user_timeline/
http://a1.twimg.com/profile_images/
En este archivo cacheamos todos los archivos estáticos y permitimos acceso a la url que devuelve los tweets y a la devuelve las imágenes de usuario.
El servidor debe devolver este archivo con el MIME text/cache-manifest o no funcionará.
Dos notas:
Primera: existe un comentario con el número de versión. Esto no es necesario, pero nos sirve para indicar al navegador que la aplicación ha sido actualizada y tiene que volver a cachearla. Esto es así porque una vez cacheados todos los archivos, en caso de cambiar el contenido de uno de ellos el navegador no se dará cuenta porque usará su versión cacheada. Sólo se da cuenta de que ha habido algún cambio cuando el fichero de manifiesto cambia.
Segunda: en la sección NETWORK he usado el comodín * qué indica cualquier recurso externotal como está descrito en en la especificación de HTML5 referida al almacenamiento offline, pero no compatible con iPhone OS, por lo que he especificado la urls de los recursos que necesitamos accesibles.
Actualizando la aplicación
El Objeto que maneja el almacenamiento offline es window.applicationCache. Este objeto contiene el estado de la caché así como funciones de actualización entre otras.
En cualquier momento podemos ver el estado de la caché con la propiedad status:
window.applicationCache.status
Esto nos devuelve un número de la siguiente tabla:
- 0: la aplicación no está cacheada (uncached)
- 1: los archivos están cacheados (idle)
- 2: la actualización ha empezado pero no se ha descargado nada (checking)
- 3: descargando los archivos a la caché (downloading)
- 4: los ficheros se han descargado y la nueva caché esta lista para ser usada (updateready)
- 5: obsoleto, el manifiesto ya no existe (obsolete)
Cada vez que el 'status' cambia se produce un evento. A nosotros nos interesa el evento updateready. Cuando se produzca (porque hemos actualizado el manifiesto) actualizaremos la aplicación:
<script type="text/javascript" charset="utf-8">
function updateCache(){
window.applicationCache.update();
window.applicationCache.swapCache();
}
$(window.applicationCache).bind('updateready', updateCache);
</script>
applicationCache.update() actualiza la aplicación y applicationCache.swapCache() sustituye la caché activa con la última versión.
Demo
He modificado la aplicación para ofrecer almacenamiento de datos local, por lo que cada vez que obtengamos la lista de los últimos tweets, éstos serán guardados también en el navegador, como ya vimos en el árticulo Almacenamiento local con HTML.
De esta forma, si ejecutamos la aplicación sin conexión obtendremos un listado de los últimos tweets obtenidos.







Hola, disculpa, solo queria saber como dejar fijo el toolbar, osea que cuando carguen muchos elementos y no den en la pantallay se deslice para abajo, el toolbar quede fijo. Ya intente en el css poniendolo static y con todas las propiedades de position, pero nada creo que es por la herencia. Gracias por tu ayuda