ios 如何处理 UIWebView 中的应用程序 URL?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4299403/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to handle app URLs in a UIWebView?
提问by theory
I recently found that my UIWebView was choking on ITMS links. Specifically, from the UIWebView in my app, if I navigate to a site such as this oneand click the "Available on the App Store" link, UIWebView would error out with "Error Domain=WebKitErrorDomain Code=101 The URL can't be shown."
我最近发现我的 UIWebView 被 ITMS 链接阻塞了。具体而言,在我的应用程序中的UIWebView,如果我浏览到一个网站,如这一个,然后单击“可用在App Store上的”链接,将UIWebView的错误了“错误域= WebKitErrorDomain代码= 101的网址不能显示。”
After a bit of Googling, I realized that I needed to catch requests for app links and have iOS handle them. I started out by looking to see if the scheme starts with "itms" in -webView:shouldStartLoadWithRequest:navigationType:
, but realized that there might be other kinds of app links that the system can handle. So I came up with this, instead:
经过一番谷歌搜索后,我意识到我需要捕获对应用程序链接的请求并让 iOS 处理它们。我首先查看该方案是否以 中的“itms”开头-webView:shouldStartLoadWithRequest:navigationType:
,但意识到系统可以处理其他类型的应用程序链接。所以我想出了这个,而不是:
- (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…
}
I have two questions about this:
我对此有两个问题:
- Is this sane? I'm specifically checking for the error domain and error code and fetching the URL string from the userInfo. Is that stuff likely to remain?
- This does work for the above-linked app store link, but when I switch back to my app, there appears to have been a subsequent failed request that failed with "Frame load interrupted". how can I get rid of that? It doesn't happen when I have the OS handle the request from
-webView:shouldStartLoadWithRequest:navigationType:
, so it's a bit annoying.
- 这是理智的吗?我专门检查错误域和错误代码,并从 userInfo 中获取 URL 字符串。那东西可能会留下吗?
- 这确实适用于上面链接的应用程序商店链接,但是当我切换回我的应用程序时,似乎有一个后续失败的请求因“帧加载中断”而失败。我怎样才能摆脱它?当我让操作系统处理来自 的请求时不会发生这种情况
-webView:shouldStartLoadWithRequest:navigationType:
,所以有点烦人。
How do youhandle such requests?
您如何处理此类请求?
回答by theory
Here's what I came up with. In webView:shouldStartLoadWithRequest:navigationType:
, I ask the OS to handle any non-http and non-https requests that it can, like so:
这是我想出的。在 中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;
}
This works very well except for the bloody "Frame Load Interrupted" error. I had thought that by returning false from webView:shouldStartLoadWithRequest:navigationType:
that the web view would not load the request and therefore there would be no errors to handle. But even though I return NO
above, I still "Frame Load Interrupted" error. Why is that?
除了血腥的“帧加载中断”错误外,这非常有效。我原以为通过从webView:shouldStartLoadWithRequest:navigationType:
web 视图中返回 false不会加载请求,因此不会有任何错误需要处理。但即使我返回NO
上面,我仍然“帧加载中断”错误。这是为什么?
Anyway, I'm assuming it can be ignored in -webView:didFailLoadWithError:
:
无论如何,我假设它可以在-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…
}
And now iTunes URLs work properly, as do mailto:
s and app links.
现在 iTunes URL 正常工作,mailto:
s 和应用程序链接也是如此。
回答by Steve Spencer
Starting with Theory's code, examine the URL for "itms" scheme(s) (this method can be called multiple times due to redirects). Once you see an "itms" scheme, stop the webView from loading and open the URL with Safari. My WebView happens to be in a NavigationController, so I pop out of that after opening Safari (less flashing).
从 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;
}
}
回答by Adam Eberbach
Does it help if you register your app for handling itms: links?
如果您注册您的应用程序来处理它是否有帮助:链接?
e.g. http://inchoo.net/iphone-development/launching-application-via-url-scheme/
例如 http://inchoo.net/iphone-development/launching-application-via-url-scheme/
You may start with scheme http
but then get an itms
redirect, which could fail if your app is not registered as handling that scheme.
您可以从方案开始,http
然后获得itms
重定向,如果您的应用程序未注册为处理该方案,则重定向可能会失败。