使用带有loadHTMLString / loadData的UIWebView可以打破后退和前进按钮,解决方法?

时间:2010-01-05 22:48:52

标签: iphone caching uiwebview

嵌入式UIWebViews存在一个已知问题,如果使用loadHTMLString或loadData将数据加载到其中,则canGoBack / canGoForward属性和goBack / goForward方法不起作用。这些仅在使用loadRequest时有效。

由于Safari的普通应用程序缓存在嵌入式UIWebViews中不起作用,因此创建一个有效缓存其他实时内容的本机应用程序变得不可能/无法使用。也就是说,我可以缓存HTML,Javascript,图像等的内容,并通过loadHTMLString或loadData加载它们,但后退和前进按钮不起作用。

我还可以使用loadRequest并指定文件URL,但在与实际站点通信时会中断 - 即使我指定了标记(因为cookie域问题)。

我有一个解决方法,涉及使用本地存储基本上重新实现应用程序缓存(并且没有本机应用程序自己进行任何缓存),这是可以的,但不是很理想。有没有其他的工作/我错过的东西?

5 个答案:

答案 0 :(得分:2)

我正在使用UIWebView的canGoBack检查我是否在历史的第一页。如果我那么我只是调用我用来加载第一页的小方法(displayLocalResource设置HTMLString并将其加载到webView中)。这是一个片段:

//Implementing a back button
- (void)backOne:(id)sender{
    if ([webView canGoBack]) {
        // There's 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];
        }
    }

答案 1 :(得分:1)

那么您自己下载HTML,然后将其作为字符串传递给UIWebView吗?为什么这样?你是在动态修改它还是什么?

也许自定义网址架构会有所帮助?你将loadRequest与你自己的模式一起使用,然后使用HTTP,然后将webview提供给你想要的任何数据吗?

答案 2 :(得分:0)

您是否可以获取内容,将其保存到本地文件系统,使用file:// URL将webview指向本地文件系统,然后使用shouldStartLoadWithRequest拦截链接以获取更多本地fs,在新的本地内容中指向webview等等?

我对UIWebView和file:/// URL运气不错。基本上你会拦截加载请求,自己获取东西,用重写的URL将其写入本地文件系统,然后将其加载到浏览器中。

似乎无法加载/保存浏览器历史记录。

答案 3 :(得分:0)

将字符串加载到临时文件中并将其用作URL请求似乎可以解决这个问题。这是关于直接加载字符串导致UIWebView不能将其视为您可以导航回的主页。这段代码对我有用:

//If you load the string like this, then "webView.canGoBack" never returns YES. It's 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;
    }
}

答案 4 :(得分:0)

我遇到了同样的问题。我试过管理历史,但它容易出错。现在我发现了一个更好的解决方案。

您要做的只是将loadRequest添加到about: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。只需通过堆栈来记录所有字符串响应并在每个loadHTMLString上插入about:blank。每当回到about:blank时,弹出堆栈。