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

我最近发现我的UIWebView在ITMS链接上窒息。 具体来说,从我的应用程序中的UIWebView,如果我导航到这样的网站,并单击“在App Store上可用”链接,UIWebView将错误与“错误域= WebKitErrorDomain代码= 101 URL不能显示“。

谷歌search了一下后,我意识到我需要赶上应用程序链接的请求,并有iOS处理它们。 我开始通过-webView:shouldStartLoadWithRequest:navigationType:来查看该scheme是否以“itms”开始,但是意识到系统可能会处理其他types的应用程序链接。 所以我想出了这个,而是:

 - (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获取URLstring。 这些东西可能会保留吗?
  2. 这适用于上面链接的app store链接,但是当我切换回到我的应用程序时,似乎有一个后来失败的请求失败,“帧负载中断”。 我怎么能摆脱这一点? 当操作系统处理来自-webView:shouldStartLoadWithRequest:navigationType:的请求时,不会发生这种情况,所以这有点烦人。

你如何处理这样的要求?

这是我想出来的。 在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 webView:shouldStartLoadWithRequest:navigationType: Web视图不会加载请求,因此将没有error handling。 但即使我返回上面的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 URL可以正常工作,就像mailto:和app链接一样。

从理论的代码开始,检查“itms”scheme的URL(这个方法可以被redirect多次调用)。 一旦你看到一个“itms”scheme,停止加载webView,并用Safari打开URL。 我的WebView恰好在一个NavigationController中,所以我打开后Safari浏览器(less闪烁)popup。

 - (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; } } 

它是否有帮助,如果你注册你的应用程序处理itms:链接?

例如http://inchoo.net/iphone-development/launching-application-via-url-scheme/

你可以从httpscheme开始,然后得到一个itmsredirect,如果你的应用程序没有被注册为处理该scheme,这可能会失败。