如何在UIWebView中处理应用程序URL?

时间:2010-11-28 22:10:11

标签: iphone cocoa ios uiwebview uiwebviewdelegate

我最近发现我的UIWebView在ITMS链接上窒息。具体来说,从我的应用程序中的UIWebView,如果我导航到this one等网站并单击“App Store上的可用”链接,UIWebView将错误输出“Error Domain = WebKitErrorDomain Code = 101该URL可以不会出现。“

经过一段谷歌搜索,我意识到我需要捕获应用程序链接的请求并让iOS处理它们。我开始时查看该方案是否以-webView:shouldStartLoadWithRequest:navigationType:中的“itms”开头,但意识到可能存在系统可以处理的其他类型的应用程序链接。所以我想出了这个,而不是:

- (void)webView:(UIWebView *)wv didFailLoadWithError:(NSError *)error {
    // Give iOS a chance to open it.
    NSURL *url = [NSURL URLWithString:[error.userInfo objectForKey:@"NSErrorFailingURLStringKey"]];
    if ([error.domain isEqual:@"WebKitErrorDomain"]
        && error.code == 101
        && [[UIApplication sharedApplication]canOpenURL:url])
    {
        [[UIApplication sharedApplication]openURL:url];
        return;
    }

    // Normal error handling…
}

我有两个问题:

  1. 这样理智吗?我专门检查错误域和错误代码,并从userInfo中获取URL字符串。这些东西可能会留下吗?
  2. 这适用于上面链接的应用商店链接,但当我切换回我的应用时,似乎有一个后续失败的请求因“帧加载中断”而失败。我怎么能摆脱那个?当我让操作系统处理来自-webView:shouldStartLoadWithRequest:navigationType:的请求时,它不会发生,所以它有点烦人。
  3. 如何处理此类请求?

3 个答案:

答案 0 :(得分:90)

这就是我想出的。在webView:shouldStartLoadWithRequest:navigationType:中,我要求操作系统处理任何非http和非https请求,如下所示:

- (BOOL)webView:(UIWebView *)wv shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {

    // Determine if we want the system to handle it.
    NSURL *url = request.URL;
    if (![url.scheme isEqual:@"http"] && ![url.scheme isEqual:@"https"]) {
        if ([[UIApplication sharedApplication]canOpenURL:url]) {
            [[UIApplication sharedApplication]openURL:url];
            return NO;
        }
    }
    return YES;
}

除了血腥的“帧加载中断”错误之外,这种方法非常有效。我原以为通过从webView:shouldStartLoadWithRequest:navigationType:返回false,Web视图不会加载请求,因此不会有错误处理。但即使我上面返回NO,我仍然会“帧加载中断”错误。那是为什么?

无论如何,我假设在-webView:didFailLoadWithError:中可以忽略它:

- (void)webView:(UIWebView *)wv didFailLoadWithError:(NSError *)error {
    // Ignore NSURLErrorDomain error -999.
    if (error.code == NSURLErrorCancelled) return;

    // Ignore "Fame Load Interrupted" errors. Seen after app store links.
    if (error.code == 102 && [error.domain isEqual:@"WebKitErrorDomain"]) return;

    // Normal error handling…
}

现在iTunes网址正常运行,mailto:和应用链接也是如此。

答案 1 :(得分:8)

从Theory的代码开始,检查“itms”方案的URL(由于重定向,可以多次调用此方法)。一旦看到“itms”方案,停止加载webView并使用Safari打开URL。我的WebView恰好在NavigationController中,所以在打开Safari(闪烁少)之后我会弹出它。

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request 
  navigationType:(UIWebViewNavigationType)navigationType 
{
    if ([[[request URL] scheme] isEqualToString:@"itms-apps"]) {
        [webView stopLoading];
        [[UIApplication sharedApplication] openURL:[request URL]];
        [self.navigationController popViewControllerAnimated:YES];
        return NO;
    } else {
        return YES;
    }
}

答案 2 :(得分:-2)

如果您注册处理itms的应用程序有用吗:链接?

e.g。 http://inchoo.net/iphone-development/launching-application-via-url-scheme/

您可以从方案http开始,然后获得itms重定向,如果您的应用未注册为处理该方案,则可能会失败。