Можно ли кэшировать ресурсы, загруженные в 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
.
Ответы
Ответ 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).