2010-08-13 13 views
8

Stiamo costruendo applicazioni Web per iPhone che funzionano offline. Ma abbiamo difficoltà a memorizzare le immagini dinamiche nella cache. Per favore continua a leggere e mostrerò con esattezza cosa intendo e cosa abbiamo fatto finora.HTML5 iPhone caching dinamico delle immagini

Quindi, ad esempio, diciamo che stiamo costruendo una semplice applicazione di lista con solo 1 pagina. L'unico scopo dell'applicazione è quello di elencare 5 voci, ciascuna contenente un testo e 1 immagine.

L'applicazione ha un semplice logo e alcuni codici JavaScript e CSS separati. Queste risorse statiche vengono memorizzate nella cache utilizzando il file manifest della cache.

Ci sono 2 scenario di:

Scenario 1: Sono online e apro l'applicazione web

Quando carico l'applicazione lista in Safari sarà prendere 5 nuovi oggetti casuali su un database contenente migliaia di elementi. Questi sono tutti serviti da backend semplice attraverso una chiamata AJAX (in formato JSON).

L'intero oggetto JSON contenente i 5 elementi viene immediatamente archiviato nella memoria locale HTML5 e memorizzato nella cache per l'utilizzo offline.

struttura dell'oggetto JSON è un po 'come questo:

{ 
    "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" 
    } 
} 

Come si può vedere, molto semplice (possono essere alcuni errori in quella JSON), l'intero oggetto JSON è memorizzato nella memoria locale.

Ora i 5 elementi sono resi utilizzando HTML JavaScript iniettato (con stile CSS), niente di eccezionale. I tag di estensione contenenti i tag di testo e immagine che puntano alla risorsa immagine vengono creati ecc.

In modalità online, tutto funziona alla grande.

Scenario 2: Sono offline e apro l'applicazione web

La pagina carichi (il logo viene visualizzato perché è stato memorizzato nella cache come una risorsa statica usando la cache manifesto), un po 'di JavaScript rileva che siamo davvero offline e l'applicazione come risultato non tenta di contattare il back-end. Invece legge l'oggetto JSON memorizzato in precedenza dalla memoria locale e avvia il rendering dei 5 elementi. Tutto come previsto.

Il testo viene visualizzato correttamente, ma questa volta le immagini non vengono visualizzate, motivo per cui è semplice, i tag immagine puntano a risorse di immagini che non sono disponibili. In questo modo viene visualizzata l'icona piccola immagine non disponibile.


Ora la mia domanda è, c'è un modo per memorizzare le risorse di immagine in qualche modo? In modo che la prossima volta che ne abbiamo bisogno, vengono recuperati dalla cache.

Questo è quello che ho provato:

  • Base64 codificare le immagini e fornire loro attraverso JSON. Funziona MA, aumenta drasticamente sia il recupero che il tempo di rendering (stiamo parlando di un aumento di 30 secondi, molto lento)
  • Alcuni cache manifest hacking/tentativi ed errori ..non è riuscito a trovare nulla che funzioni (idealmente è necessario un criterio che "memorizza tutte le risorse sul dominio quando vengono richieste", ma a mia conoscenza questo non esiste)

Ho letteralmente trascorso ore su questo e posso trovare una soluzione ... qualcuno ha la minima idea? So che questo è possibile perché se guardi l'applicazione HTML5 di Google Mail per l'iPhone, possono in qualche modo memorizzare nella cache gli allegati e puoi recuperarli anche offline.

L'unica cosa che non abbiamo provato è l'utilizzo dei database SQLite supportati da Safari ... forse potrei memorizzare le immagini come un BLOB (vuol dire comunque recuperarlo dal feed e quindi lento?) E poi in qualche modo convertirlo magicamente in un'immagine sullo schermo ... ma non ho idea di come farlo.

Qualsiasi aiuto è apprezzato, grazie.

risposta

1

Vorrei consigliarvi di dare un'occhiata per vedere se è possibile utilizzare le tele per contenere le immagini, in quanto hanno determinate proprietà per ottenere/inserire dati di pixel dell'immagine, come un CSV di valori di pixel (0-255).

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

non sono sicuro se è possibile utilizzare in modo dinamico fonti di immagini in una tela, ma se si può si dovrebbe essere in grado di trasferire i dati CSVV dall'immagine ad un DB e viceversa.

Spero che ti porti da qualche parte.

Quota

Safari 4.0 e successivi supportano manipolazione diretta dei pixel di una tela. È possibile ottenere i dati grezzi dei pixel di una tela con la funzione getImageData() e creare un nuovo buffer per i pixel manipolati con la funzione createImageData().


Aggiornamento:.

ho trovato questo link si può anche essere interessati a

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

http://wecreategames.com/blog/?p=219 // Si noti inoltre l'idea con tela serializzazione :)

+0

Grazie per la risposta - si fanno un buon punto lì non ho pensato di farlo. Ho familiarità con l'elemento canvas, quindi dovrei essere in grado di provarlo al più presto. Ora speriamo solo che più tele funzionino in modo accettabile su iPhone. Riporterò qui di seguito con i risultati. –

+0

ive aggiornato il mio post con alcune altre informazioni su questo. – RobertPitt

+0

Grazie, il secondo link era esattamente quello che volevo ...sembra che memorizzino l'elemento canvas serializzato generando una rappresentazione base64. E per la visualizzazione di immagini memorizzate nella cache, creano un oggetto Immagine che punta alla stringa base64 (dal DB) pre-fissata da "data: base64", quindi questo oggetto Immagine viene disegnato sull'area di disegno. Grazie mille per il tuo aiuto. –

2

Ecco un codice che scarica un'immagine da AJAX e la converte in base64 stringa. Con questa stringa puoi salvarla su localStorage e assegnarla alla proprietà src di una img offline.

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(); 

È possibile verificare qui: http://jsbin.com/ivifiy/1/edit

Con questa tecnica è possibile scrivere una cache localStorage.

Il _arrayBufferToBase64 viene estratto da qui: ArrayBuffer to base64 encoded string

+0

Uint8Array non è mai esistito 3 anni fa nei principali browser Web, ma una buona soluzione per i browser Web più moderni :) –

Problemi correlati