2010-08-13 14 views
8

Estamos creando aplicaciones web para el iPhone que funcionan sin conexión. Pero estamos teniendo dificultades para almacenar imágenes dinámicas en caché. Siga leyendo y mostraré con ejemplos exactamente lo que quiero decir y lo que hemos hecho hasta ahora.HTML5 iPhone caché dinámico de imágenes

Por ejemplo, digamos que estamos construyendo una aplicación de lista simple con solo 1 página. El único propósito de la aplicación es enumerar 5 elementos, cada elemento que contiene texto y 1 imagen.

La aplicación tiene un logotipo simple y algunos códigos JavaScript y CSS separados. Estos recursos estáticos se almacenan en caché utilizando el archivo de manifiesto de caché.

hay 2 escenario de:

Escenario 1: Estoy en línea y abro la aplicación web

Cuando cargo la aplicación de lista en Safari se ha podido ir a 5 nuevos artículos al azar de cada una base de datos que contiene 1000 de artículos. Todos son servidos por backend simple a través de una llamada AJAX (formato JSON).

Todo el objeto JSON que contiene los 5 elementos se almacena inmediatamente en el almacenamiento local HTML5 y se almacena en caché para su uso sin conexión.

Estructura del objeto JSON es un poco como esto:

{ 
    "0" : { 
     id: "3", 
     text: "Some text about item #3", 
     image_url: "http://www.domain.com/image22341.png" 
    }, 
    "1" : { 
     id: "23", 
     text: "Some text about item #23", 
     image_url: "http://www.domain.com/image442321.png" 
    }, 
    "2" : { 
     id: "4", 
     text: "Some text about item #4", 
     image_url: "http://www.domain.com/image2321.png" 
    }, 
    "3" : { 
     id: "432", 
     text: "Some text about item #432", 
     image_url: "http://www.domain.com/image2441.png" 
    }, 
    "4" : { 
     id: "43", 
     text: "Some text about item #43", 
     image_url: "http://www.domain.com/image221.png" 
    } 
} 

Como se puede ver, muy simple (puede haber algunos errores en que JSON), todo el objeto JSON se almacena en el almacenamiento local.

Ahora los 5 elementos se representan con JavaScript inyectado HTML (estilo con CSS), nada sofisticado. Las etiquetas de expansión que contienen las etiquetas de texto e imagen que apuntan al recurso de imagen se crean, etc.

En el modo en línea, todo funciona muy bien.

Escenario 2: No estoy conectado y abro la aplicación web

Las página se carga (se muestra el logotipo, ya que se almacena en caché como un recurso estático mediante el manifiesto de caché), algo de JavaScript que detecta de hecho estamos fuera de línea y la aplicación como resultado no intenta contactar al back-end. En su lugar, lee el objeto JSON previamente almacenado del almacenamiento local y comienza a renderizar los 5 elementos. Todo como se anticipó.

El texto se muestra bien, pero esta vez, las imágenes no se muestran, razón por la cual es simple, las etiquetas de imagen apuntan a recursos de imágenes que no están disponibles. Por lo tanto, muestra ese pequeño icono de imagen no disponible.


Ahora mi pregunta es, ¿hay alguna forma de almacenar en caché esos recursos de imágenes de alguna manera? Para que la próxima vez que los necesitemos, se obtengan de la memoria caché.

Esto es lo que he intentado:

  • Base64 codificar las imágenes y suministrarlos a través de JSON. Esto funciona, PERO, aumenta drásticamente tanto el tiempo de búsqueda como el de renderizado (estamos hablando de un aumento de 30 segundos, muy lento)
  • Caché de manifiesto de algunos caché/prueba y error.no pude encontrar nada que funcione (idealmente necesito una política que 'cache todos los recursos en el dominio tal como se solicitan', pero que yo sepa esto no existe)

Literalmente he pasado horas en esto y puedo no encuentras una solución ... ¿Alguien tiene una pista? Sé que esto es posible porque si miras la aplicación HTML5 de Google Mail para el iPhone, de alguna manera pueden almacenar en caché los archivos adjuntos y puedes recuperarlos incluso sin conexión.

Lo único que no hemos intentado es utilizar las bases de datos SQLite que son compatibles con Safari ... ¿tal vez podría almacenar las imágenes como BLOB (todavía significa recuperarlo de la fuente y por lo tanto ralentizar?) Y luego de alguna manera mágicamente convirtiendo eso en una imagen en la pantalla ... pero no tengo idea de cómo hacer esto.

Se agradece cualquier ayuda, gracias.

Respuesta

1

Le aconsejo que eche un vistazo para ver si puede usar lienzos para contener sus imágenes, ya que tienen ciertas propiedades para obtener/insertar datos de píxeles de imagen, como un CSV de valores de píxeles (0-255).

Fuente: http://developer.apple.com/safari/library/documentation/appleapplications/conceptual/SafariJSProgTopics/Tasks/Canvas.html

no estoy seguro si se puede usar de forma dinámica las fuentes de imagen en un lienzo, pero si puede usted debe ser capaz de transferir los datos CSVV de la imagen a una base de datos y viceversa.

Espero que te lleve a algún lado.

Cita

Safari 4.0 y posteriores admiten la manipulación directa de los píxeles de un lienzo. Puede obtener los datos de píxel sin formato de un lienzo con la función getImageData() y crear un nuevo búfer para los píxeles manipulados con la función createImageData().


Actualización:.

encontré este vincula también podría estar interesado en

http://wecreategames.com/blog/?p=210

http://wecreategames.com/blog/?p=219 // También tenga en cuenta la idea con la serialización de lona :)

+0

Gracias por su respuesta - que hacen un buen punto allí no había pensado en hacer eso. Estoy familiarizado con el elemento canvas, así que debería poder probarlo pronto. Ahora esperemos que los lienzos múltiples funcionen de forma aceptable en el iPhone. Informaré aquí con resultados más adelante. –

+0

he actualizado mi publicación con otra información sobre esto. – RobertPitt

+0

Gracias, el segundo enlace era exactamente lo que quería ...parece que almacenan el elemento canvas en serie generando una representación base64. Y para mostrar imágenes almacenadas en caché, crean un objeto Imagen que apunta a la cadena base64 (del DB) preestablecida por "data: base64", este objeto Image se dibuja en el lienzo. Muchas gracias por tu ayuda otra vez. –

2

Aquí hay un código que descarga una imagen de AJAX y la convierte a una base64 cuerda. Con esta cadena, puede guardarla en localStorage y asignarla a la propiedad src de un img sin conexión.

function _arrayBufferToBase64(buffer) { 
    var binary = ''; 
    var bytes = new Uint8Array(buffer); 
    var len = bytes.byteLength; 
    for (var i = 0; i < len; i++) { 
     binary += String.fromCharCode(bytes[ i ]); 
    } 
    return window.btoa(binary); 
} 


var xhr = new XMLHttpRequest(); 
xhr.open('GET', 'an_image.png', true); 
xhr.responseType = 'arraybuffer'; 

xhr.onload = function(e) { 
     if (this.status == 200) { 
      var string_with_bas64_image = _arrayBufferToBase64(this.response); 

      // You can save this string to local storag or set it to an img elemment this way 

      document.getElementById("img").src = "data:image/png;base64," + string_with_bas64_image; 
     } 
}; 

xhr.send(); 

Puedes probarlo aquí: http://jsbin.com/ivifiy/1/edit

Con esta técnica se puede escribir una caché localStorage.

El _arrayBufferToBase64 se extrae de aquí: ArrayBuffer to base64 encoded string

+0

Uint8Array nunca existió hace 3 años en los principales navegadores web, pero es una buena solución para los navegadores web más modernos :) –

Cuestiones relacionadas