Как обрабатывать 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…
}

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

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

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

3 58

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