HTML5 iPhone динамическое кеширование изображений - PullRequest
8 голосов
/ 13 августа 2010

Мы создаем веб-приложения для iPhone, которые работают в автономном режиме. Но у нас возникают трудности с кэшированием динамических изображений. Пожалуйста, продолжайте читать, и я покажу на примере, что именно я имею в виду и что мы уже сделали.

Так, например, скажем, мы создаем простое приложение со списком всего с 1 страницей. Единственная цель приложения - перечислить 5 элементов, каждый из которых содержит некоторый текст и 1 изображение.

Приложение имеет простой логотип и отдельный код JavaScript и CSS. Эти статические ресурсы кэшируются с использованием файла манифеста кэша.

Есть 2 сценария:

Сценарий 1: я в сети и открываю веб-приложение

Когда я загружаю приложение списка в Safari, оно извлекает 5 новых случайных элементов из базы данных, содержащей 1000 элементов. Все они обслуживаются простым бэкэндом через вызов AJAX (формат JSON).

Весь объект JSON, содержащий 5 элементов, немедленно сохраняется в локальном хранилище HTML5 и кэшируется для автономного использования.

Структура объекта JSON выглядит примерно так:

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

Как видите, очень просто (могут быть некоторые ошибки в этом JSON), весь объект JSON хранится в локальном хранилище.

Теперь 5 элементов отображаются с использованием HTML-кода, внедренного в JavaScript (в стиле CSS), ничего особенного. Создаются теги Span, содержащие теги text и image, указывающие на ресурс изображения, и т. Д.

В онлайн режиме все отлично работает.

Сценарий 2. Я в автономном режиме и открываю веб-приложение

Страница загружается (логотип отображается потому, что он был кэширован как статический ресурс с использованием манифеста кэша), некоторые JavaScript обнаруживают, что мы действительно отключены, и в результате приложение не пытается связаться с бэкэндом. Вместо этого он читает ранее сохраненный объект JSON из локального хранилища и начинает рендеринг 5 элементов. Все как и ожидалось.

Текст отображается нормально, но на этот раз изображения не отображаются, причина этого проста, теги изображения указывают на ресурсы изображения, которые недоступны. Так что это маленькое изображение отображает недоступный значок.


Теперь мой вопрос: есть ли способ как-то кэшировать эти ресурсы изображений? Так что в следующий раз, когда они нам понадобятся, они будут извлечены из кэша.

Вот что я пробовал:

  • Base64 кодирует изображения и передает их через JSON. Это работает НО, оно значительно увеличивает время выборки и рендеринга (речь идет об увеличении на 30 секунд, очень медленно)
  • Некоторые кеш-манифесты взлома / проб и ошибок .. не смогли найти ничего, что работает (в идеале нужна политика, которая «кэширует все ресурсы в домене по мере их запроса», но, насколько мне известно, этого не существует)

Я буквально потратил несколько часов на это и не могу найти решение ... у кого-нибудь есть подсказка? Я знаю, что это возможно, потому что, если вы посмотрите на приложение Google Mail HTML5 для iPhone, они могут каким-то образом кэшировать вложения, и вы сможете получать их даже в автономном режиме.

Единственное, что мы не пробовали, - это использовать базы данных SQLite, которые поддерживаются Safari ... может быть, я мог бы сохранить изображения в виде BLOB (все еще означает получение их из ленты и, следовательно, замедление?), А затем каким-то волшебным образом преобразовать это в изображение на экране .... но я понятия не имею, как это сделать.

Любая помощь приветствуется, спасибо.

Ответы [ 2 ]

2 голосов
/ 02 июня 2013

Вот код, который загружает изображение из AJAX и конвертирует его в строку base64. С помощью этой строки вы можете сохранить ее в localStorage и присвоить ее свойству src img в автономном режиме.

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

Вы можете проверить это здесь: http://jsbin.com/ivifiy/1/edit

С помощью этой техники вы можете написать кэш localStorage.

_arrayBufferToBase64 извлекается отсюда: ArrayBuffer для кодированной строки base64

1 голос
/ 13 августа 2010

Я бы посоветовал вам посмотреть, можно ли использовать холсты для хранения изображений, поскольку они обладают определенными свойствами для получения / вставки данных пикселей изображения, например, CSV значений пикселей (0-255).

Источник: https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/HTML-canvas-guide/PixelManipulation/PixelManipulation.html

Я не уверен, что вы можете динамически использовать источники изображений на холсте, но если вы можете, вы сможете передавать данные CSVV из изображения в БД и наоборот.

Цитата

Safari 4.0 и более поздние версии поддерживают прямое манипулирование пикселями холста. Вы можете получить необработанные данные пикселей холста с помощью функции getImageData () и создать новый буфер для манипулируемых пикселей с помощью функции createImageData ().

( источник на archive.org )


Обновление:

Я нашел эти ссылки, которые могут вас также заинтересовать.

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

http://wecreategames.com/blog/?p=219 // Также обратите внимание на идею с сериализацией canvas:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...