iphone - per - webkit tutorial swift




Come gestire gli URL delle app in un UIWebView? (2)

Recentemente ho scoperto che il mio UIWebView stava soffocando sui collegamenti ITMS. In particolare, da UIWebView nella mia app, se si naviga in un sito come questo e si fa clic sul collegamento "Disponibile sull'App Store", UIWebView genera un errore con "Dominio errore = Codice WebKitErrorDomain = 101 L'URL non può essere mostrato."

Dopo un po 'di ricerca su Google, mi sono reso conto che dovevo catturare le richieste per i collegamenti delle app e farle gestire da iOS. Ho iniziato cercando di vedere se lo schema inizia con "itms" in -webView:shouldStartLoadWithRequest:navigationType: ma -webView:shouldStartLoadWithRequest:navigationType: capito che potrebbero esserci altri tipi di collegamenti di app che il sistema può gestire. Quindi mi sono inventato questo, invece:

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

Ho due domande a riguardo:

  1. È sano di mente? Sto specificatamente controllando il dominio di errore e il codice di errore e recuperando la stringa dell'URL da userInfo. È probabile che rimanga quella roba?
  2. Questo funziona per il link all'app store sopraindicato, ma quando torno alla mia app, sembra che ci sia stata una successiva richiesta non riuscita che ha avuto esito negativo con "Frame load interrupted". come posso liberarmene? Non succede quando il sistema operativo gestisce la richiesta da -webView:shouldStartLoadWithRequest:navigationType: quindi è un po 'fastidioso.

Come gestisci tali richieste?


A partire dal codice della teoria, esaminare l'URL per gli schemi "itms" (questo metodo può essere chiamato più volte a causa di reindirizzamenti). Quando visualizzi uno schema "itms", interrompi il caricamento della webView e apri l'URL con Safari. La mia WebView si trova in un NavigationController, quindi ne esco fuori dopo aver aperto Safari (meno lampeggiante).

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

Ecco cosa mi è venuto in mente. In webView:shouldStartLoadWithRequest:navigationType: chiedo al sistema operativo di gestire le richieste non http e non https che può, in questo modo:

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

Funziona molto bene tranne per il sanguinoso errore "Frame Load Interrupted". Avevo pensato che restituendo false da webView:shouldStartLoadWithRequest:navigationType: che la vista web non avrebbe caricato la richiesta e quindi non ci sarebbero stati errori da gestire. Ma anche se restituisco NO sopra, ho ancora errore "Frame Load Interrupted". Perché?

Ad ogni modo, -webView:didFailLoadWithError: che possa essere ignorato in -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…
}

E ora gli URL di iTunes funzionano correttamente, così come i collegamenti mailto: s e app.





uiwebviewdelegate