Как обрабатывать URL-адреса приложений в UIWebView?
недавно я обнаружил, что мой UIWebView задыхался от ссылок ITMS. В частности, из UIWebView в моем приложении, если я перейду на сайт, такой как этот и нажмите ссылку "доступно в магазине приложений", UIWebView выдаст ошибку с " Error Domain=WebKitErrorDomain Code=101 URL-адрес не может быть показан."
немного погуглив, я понял, что мне нужно ловить запросы на ссылки на приложения и обрабатывать их 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…
}
у меня два вопроса по этому поводу:
- это нормально? Я специально проверяю домен ошибки и код ошибки и извлекаю строку URL из userInfo. Это вещество, вероятно, останется?
- это работает для ссылки на магазин приложений, связанной выше, но когда я переключаюсь обратно в свое приложение, там кажется, был последующий неудачный запрос, который не удался с "Frame load interrupted". как я могу избавиться от этого? Это не происходит, когда у меня есть ОС обрабатывать запрос от
-webView:shouldStartLoadWithRequest:navigationType:
, Так что это немного раздражает.
как вы обрабатывать такие запросы?
3 ответа:
вот что я придумал. В
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; }
это работает очень хорошо, за исключением кровавой ошибки "Frame Load Interrupted". Я думал, что, возвращаясь false от
webView:shouldStartLoadWithRequest:navigationType:
что веб-представление не будет загружать запрос и поэтому не будет никаких ошибок для обработки. Но даже если я вернусьNO
выше, я все еще" Frame Load Interrupted " ошибка. Зачем быть это?в любом случае, я предполагаю, что его можно игнорировать в
-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:
S и ссылки на приложения.
начиная с кода теории, изучите URL для схемы (схем)" itms " (этот метод может быть вызван несколько раз из-за перенаправления). Как только вы увидите схему "itms", остановите загрузку webView и откройте URL-адрес с помощью Safari. Мой 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; } }
это поможет, если вы зарегистрируете свое приложение для обработки itms: ссылки?
например, http://inchoo.net/iphone-development/launching-application-via-url-scheme/
вы можете начать со схемы
http
а затемitms
перенаправление, которое может завершиться неудачей, если ваше приложение не зарегистрировано как обработка этой схемы.