Использование UIWebView с loadHTMLString/loadData ломает кнопки назад и вперед, обходной путь?

Известная проблема со встроенными UIWebViews заключается в том, что если вы загружаете данные в них с помощью loadHTMLString или loadData, свойства canGoBack/canGoForward и методы goBack/goForward не работают. Они работают только при использовании loadRequest.

Так как обычный кэш приложений Safari не работает во встроенных UIWebViews, создается собственное приложение, которое эффективно кэширует, иначе живой контент становится невозможным/непригодным. То есть я могу кэшировать содержимое HTML, Javascript, изображений и т.д. И загружать их через loadHTMLString или loadData, но затем кнопки назад и вперед не работают.

Я мог бы также использовать loadRequest и указать URL-адрес файла, но это ломается, когда дело доходит до общения с живым сайтом - даже если я укажу тег (из-за проблем с файлом cookie).

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

Ответ 1

Я использую UGWebView canGoBack, чтобы проверить, не находится ли я на первой странице истории. Если я тогда, я просто называю маленький метод, который я использовал для загрузки первой страницы (displayLocalResource настраивает HTMLString и загружает его в webView). Вот фрагмент:

//Implementing a back button
- (void)backOne:(id)sender{
    if ([webView canGoBack]) {
        // There a valid webpage to go back to, so go there
        [webView goBack];
    } else {
        // You've reached the end of the line, so reload your own data
            [self displayLocalResource];
        }
    }

Ответ 2

Итак, вы сами загружаете HTML-код, а затем передаете его в UIWebView в виде строки? Почему так? Вы изменяете его на лету или что-то в этом роде?

Может быть, нужна схема пользовательских URL? Вы используете loadRequest со своей собственной схемой, которая, в свою очередь, работает с HTTP, а затем передает webview любые данные, которые вы хотите?

Ответ 3

Вы можете получить содержимое, сохранить его в локальной файловой системе, указать веб-просмотр в локальную файловую систему с использованием URL-адреса://, затем перехватить ссылку следует с shouldStartLoadWithRequest, чтобы получить больше для локальных fs, point webview в новом локальном содержимом, и т.д.

Мне повезло с UIWebView и файлами:///URL. В основном вы будете перехватывать запросы загрузки, самостоятельно загружать материал, записывать его в локальную файловую систему с перезаписанными URL-адресами, а затем загружать их в браузер.

Кажется, что нет возможности загружать/сохранять историю браузера.

Ответ 4

Загрузка строки в файл temp и использование этого в качестве URL-запроса, похоже, вылечивает это. Это что-то о загрузке строки напрямую, что заставляет UIWebView не видеть ее как домашнюю страницу, на которую вы можете вернуться. Этот код работал у меня:

//If you load the string like this, then "webView.canGoBack" never returns YES. It documented frequently on the web.
//Loading the string as a URL instead seems to work better.
//[self.myWebView loadHTMLString:str baseURL:nil];

//write the string to a temp file
NSString *fileName = @"homepage.html";
NSURL *fileURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:fileName]];
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
[data writeToURL:fileURL atomically:NO];

//open that temp file in the UIWebView
[self.myWebView loadRequest:[NSURLRequest requestWithURL:fileURL]];

Используйте это, чтобы включить/отключить кнопку "Назад":

- (void)webViewDidFinishLoad:(UIWebView *)webView{
    //this is to check if we're back at the root page.
    if (webView.canGoBack == YES) {
        self.backButton.enabled=YES;
    }
    else {
        self.backButton.enabled=NO;
    }
}

Ответ 5

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

Что вы хотите сделать, просто добавьте loadRequest примерно: blank и сделайте это как заполнитель для вас, прежде чем вы вызове loadHTMLString/loadData. Тогда вы совершенно свободны от мониторинга истории. Webview.canGoBack и canGoForward будут работать. Конечно, вам понадобится взломать ручку, чтобы вернуться к заполнителю: пустым. Вы можете сделать это в webViewDidFinishLoad. Вот код:

В функции при вызове loadHTMLString:

[weakSelf.fbWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];
[weakSelf.fbWebView loadHTMLString:stringResponse baseURL:url];

Код для обработки goBack:

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
  if ([webView.request.URL.absoluteString isEqualToString:@"about:blank"]
      && ![webView canGoBack] && [webView canGoForward]) {
    [weakSelf.fbWebView loadHTMLString:stringResponse baseURL:url];
  }
}

Я думаю, что это также возможно расширить это решение, чтобы обработать эти loadHTMLString, которые не являются первой загрузкой. Просто имея Stack для записи всего ответа строки и вставьте about: blank на каждый loadHTMLString. И поместите стек, когда каждый раз вернитесь к примерно: пустое.