Как обрабатывать URL-адреса приложений в UIWebView? - PullRequest
60 голосов
/ 29 ноября 2010

Недавно я обнаружил, что мой UIWebView задыхается от ссылок ITMS.В частности, из UIWebView в моем приложении, если я перейду на такой сайт, как этот и нажму ссылку «Доступно в App Store», UIWebView выдаст ошибку «Ошибка домена = WebKitErrorDomain Code = 101».Невозможно отобразить URL. "

После небольшого поиска в Google я понял, что мне нужно отлавливать запросы на ссылки приложений и обрабатывать их в 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…
}

У меня есть два вопроса по этому поводу:

  1. Это нормально?Я специально проверяю домен ошибок и код ошибки и выбираю строку URL из userInfo.Возможно ли, что этот материал останется?
  2. Это работает для ссылки на вышеупомянутый магазин приложений, но когда я переключаюсь обратно в свое приложение, появляется, как представляется, последующий неудачный запрос, который завершился с ошибкой «Загрузка кадра прервана»».как я могу избавиться от этого?Это не происходит, когда у меня ОС обрабатывает запрос от -webView:shouldStartLoadWithRequest:navigationType:, поэтому это немного раздражает.

Как вы обрабатываете такие запросы?

Ответы [ 3 ]

90 голосов
/ 14 декабря 2010

Вот что я придумал. В 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…
}

И теперь URL-адреса iTunes работают правильно, как и mailto: s и ссылки на приложения.

8 голосов
/ 08 августа 2011

Начиная с кода Теории, изучите 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;
    }
}
0 голосов
/ 29 ноября 2010

Поможет ли вам зарегистрировать приложение для обработки ссылок itms:

например. http://inchoo.net/iphone-development/launching-application-via-url-scheme/

Вы можете начать со схемы http, но затем получить перенаправление itms, которое может завершиться ошибкой, если ваше приложение не зарегистрировано для обработки этой схемы.

...