Подтвердить что ты не робот

Можно ли кэшировать ресурсы, загруженные в iPhone UIWebView?

У меня есть простое приложение, загружающее сайт, оптимизированный для iPhone, в UIWebView.

Проблема в том, что кэширование не работает:

[webView loadRequest: [NSURLRequest requestWithURL: [NSURL URLWithString: url]
                                       cachePolicy: NSURLRequestUseProtocolCachePolicy
                                   timeoutInterval: 60.0]];

Любые вещи, упомянутые на этой удаленной странице (css, изображения, внешние файлы javascript), никогда не будут кэшироваться (запросы никогда не отправляют заголовок If-Modified-Since или что-либо еще в способе управления кешем.)

Возможно ли это? Кажется, что с обычным Cocoa WebView есть методы делегата, которые вызывают для каждого запроса на ресурс и пост-нагрузки (-didFinishLoadingFromDataSource:), которые вы могли бы использовать, чтобы свернуть свое собственное кэширование.. но это, похоже, не применимо здесь.

Вся моя страница (страница и ресурсы, на которую ссылаются) составляет около 89 Кб, что в некоторых местах медленнее, чем 3G, и даже хуже, чем у EDGE. Входящие запросы, по крайней мере, указывают на то, что он принимает сжатие (accept-encoding=gzip, deflate), поэтому я полагаю, что хорошо.

Я читаю это исследование yui, которое, похоже, указывает, что iPhone будет кэшировать 25k за элемент. Единственное, на что ссылается, что более 25k несжатых - jquery (упакованный, но несжатый - это 30k). Все остальное должно быть кэшируемым. Никакой запрос на что-либо, ссылающийся на выбранную страницу, не запускает 304 на стороне сервера.

Это исследование yui было проведено почти год назад, и я угадываю только мобильное сафари.

В приложении для родного iPhone используется UIWebView.

4b9b3361

Ответ 1

Обходной проблемой этой проблемы, как я вижу, является

1) скачать код HTML

2) сохраните его в строке

3) найти все внешние ссылки в нем, например

<img src="img.gif" width="..." height="..." />

4) загрузите их все

5) замените их на встроенную версию с кодировкой Base64

<img src="data:image/gif;base64,R0lGODlhUAAPA...JADs= " width="..." height="..." />

6), наконец, сохраните полный HTML-код со встроенными изображениями, как вы хотите.

Ответ 2

Из https://github.com/phonegap/phonegap-iphone/issues/148:

NSURLCache* cache = [NSURLCache sharedURLCache];
[cache setMemoryCapacity:4 * 1024 * 1024];
[cache setDiskCapacity:512*1024];

[NSURLRequest requestWithURL:appURL
                 cachePolicy:NSURLRequestReturnCacheDataElseLoad
             timeoutInterval:10.0];

Ответ 3

Теперь вы можете попробовать ASIWebPageRequest от All Seeing Interactive:

ASIWebPageRequest - новое экспериментальное дополнение к семейству ASIHTTPRequest. Его можно использовать для загрузки полной веб-страницы, включая внешние ресурсы, такие как изображения и таблицы стилей, в одном запросе. После загрузки веб-страницы запрос будет анализировать содержимое, искать внешние ресурсы, загружать их и вставлять непосредственно в источник html с использованием Data URIS. Затем вы можете взять ответ и поместить его прямо в UIWebView/WebView на Mac.

Я могу только посоветовать всем использовать большую библиотеку Ben Copsey для всех видов HTTP-операций.

ОБНОВЛЕНИЕ: Бен отменил ASIHTTPRequest. Я больше не предлагаю использовать его.

Ответ 4

Вы всегда можете выполнять запросы вручную, хотя это будет сложно, а затем вы можете кэшировать вещи в своем сердце. Создайте UIWebViewDelegate, который запустит запрос в webView:shouldStartLoadWithRequest:navigationType:, кеширует результат и использует UIWebView loadHTMLString:baseURL: для обновления представления.

Это будет уродливо, и все будет работать не так гладко, как вы могли бы хотеть, но это может быть достаточно для того, что вам нужно.

Ответ 5

ihone имеет ограниченную емкость кэширования по сравнению с обычным компьютером. Он ограничивает несжатые элементы кэша до 25k.

Хорошая информация здесь: http://yuiblog.com/blog/2008/02/06/iphone-cacheability/

Ответ 6

Вы должны обладать подклассом NSURLCache и подставлять его для общего кэша, используемого UIWebView, как описано в этом Cocoa с любовью: Подстановка локальных данных для удаленных запросов UIWebView

Для другого подхода рассмотрим Отключение автономного кэширования для UIWebView (и NSURLProtocol).