Jak obsługiwać adresy URL aplikacji w UIWebView?

Niedawno odkryłem, że mój UIWebView dławił się linkami ITMS. W szczególności, z UIWebView w mojej aplikacji, jeśli przejdę do witryny takiej jak Ten i kliknij link "dostępne w App Store", UIWebView będzie błąd z " Error Domain=Webkiterrordomain Code = 101 URL nie może być wyświetlany."

Po trochę googlowania, zdałem sobie sprawę, że muszę złapać prośby o linki do aplikacji i mieć iOS obsługiwać je. Zacząłem od szukania, czy program zaczyna się od "itms" w -webView:shouldStartLoadWithRequest:navigationType:, ale zdałem sobie sprawę, że mogą istnieć inne rodzaje linków do aplikacji, które system może obsługiwać. Więc wymyśliłem to, zamiast tego:

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

Mam dwa pytania na ten temat:

  1. czy to normalne? W szczególności sprawdzam domenę błędów i Kod błędu i pobieram ciąg URL z userInfo. Czy to może zostać?
  2. Działa to w przypadku powyższego linku app store, ale gdy przełączę się z powrotem do mojej aplikacji, wydaje się, że kolejna nie powiodła się żądanie, które nie powiodło się z "przerwane obciążenie Ramki". Jak mogę się tego pozbyć? Nie dzieje się tak, gdy mam system operacyjny obsługujący żądanie z -webView:shouldStartLoadWithRequest:navigationType:, więc jest to trochę denerwujące.
Jak sobie radzisz z takimi prośbami?
Author: theory, 2010-11-29

3 answers

Oto, co wymyśliłem. W webView:shouldStartLoadWithRequest:navigationType:, Proszę system operacyjny o obsługę wszelkich żądań nie-http i nie-https, które może, w ten sposób:

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

To działa bardzo dobrze, z wyjątkiem cholernego błędu "Frame Load Interrupted". Myślałem, że zwracając false z webView:shouldStartLoadWithRequest:navigationType:, widok sieci web nie załaduje żądania i dlatego nie będzie żadnych błędów do obsługi. Ale mimo, że zwracam NO powyżej, nadal "Frame Load Interrupted" błąd. Dlaczego?

W każdym razie, zakładam, że może to być ignorowane w -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…
}

I teraz adresy URL iTunes działają poprawnie, podobnie jak mailto: s i linki do aplikacji.

 89
Author: theory,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-14 18:13:14

Zaczynając od kodu teorii, zbadaj adres URL pod kątem schematów "itms" (ta metoda może być wywoływana wielokrotnie ze względu na przekierowania). Gdy zobaczysz schemat "itms", Zatrzymaj ładowanie widoku sieci Web i otwórz adres URL w przeglądarce Safari. Mój WebView dzieje się w NavigationController, więc wyskakuje z tego po otwarciu Safari(mniej miga).

- (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;
    }
}
 8
Author: Steve Spencer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-08 18:31:40

Czy pomaga Rejestracja aplikacji do obsługi ITMS: links?

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

Możesz zacząć od scheme http, ale następnie uzyskać przekierowanie itms, które może się nie udać, jeśli Twoja aplikacja nie jest zarejestrowana jako obsługująca ten schemat.

 -2
Author: Adam Eberbach,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-28 23:14:06