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

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

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

Это использование UIWebView в родном приложении для iPhone.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
11
0
29 454
6

Ответы 6

Возможности кэширования iPhone ограничены по сравнению с обычным компьютером. Он ограничивает количество элементов кэша несжатый до 25 КБ.

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

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

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

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

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 со встроенными изображениями, как хотите.

Гениально, хотя и весьма тревожно.

Orr Matarasso 11.02.2010 18:18

Лучший способ сделать это неправильно. Чувак, мы ищем здесь, по крайней мере, более удобное решение

eagle.dan.1349 18.10.2013 11:38

@ eagle.dan.1349 почему это лучший способ сделать это неправильно? при отсутствии "чуть более удобного решения" это является самое удобное решение

abbood 13.11.2013 18:43

эй, кто-нибудь подразумевает это решение? Это работает?

David 18.12.2019 22:29

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

ASIWebPageRequest is a new experimental addition to the ASIHTTPRequest family. It can be used to download a complete webpage, including external resources like images and stylesheets, in a single request. Once a web page is downloaded, the request will parse the content, look for external resources, download them, and insert them directly into the html source using Data URIS. You can then take the response and put it directly into a UIWebView / WebView on Mac.

Я могу только посоветовать всем использовать отличную библиотеку Бена Копси для всех видов HTTP-операций.

ОБНОВИТЬ: Бен прекратил поддержку ASIHTTPRequest. Я больше не предлагаю его использовать.

Привет, @rage, ты можешь предложить какие-нибудь альтернативы ASIWebPageRequest?

Kevin Zych 21.08.2013 20:25

AFNetworking довольно хорош. Также MKNetworking. Широкая публика еще не решила, какой из них станет следующим стандартом де-факто. Я не уверен, что какой-либо из них поддерживает загрузку полной веб-страницы.

rage 22.08.2013 21:50

Спасибо @rage. Я использую AFNetworking для своих вызовов API, но не для полной загрузки / кеширования веб-страницы. Я пишу приложение-контейнер, в котором размещается веб-приложение Backbone внутри UIWebview, и я ищу способы ускорить его загрузку.

Kevin Zych 23.08.2013 01:23

От 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];

Я думаю ссылка не работает

Aatish Molasi 30.04.2013 10:01

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

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

Другие вопросы по теме