iphone - que - ¿Cómo manejar las URL de la aplicación en un UIWebView?
webview swift 4 example (3)
Recientemente descubrí que mi UIWebView se estaba ahogando en los enlaces de ITMS. Específicamente, desde UIWebView en mi aplicación, si navego a un sitio como este y hago clic en el enlace "Disponible en el App Store", UIWebView podría generar un error con "Error Domain = WebKitErrorDomain Code = 101 La URL no puede ser mostrado."
Después de googlear un poco, me di cuenta de que necesitaba captar las solicitudes de enlaces de aplicaciones y que iOS las manejara. Empecé mirando para ver si el esquema comienza con "itms" en -webView:shouldStartLoadWithRequest:navigationType:
pero me di cuenta de que podría haber otros tipos de enlaces de aplicaciones que el sistema puede manejar. Así que se me ocurrió esto, en cambio:
- (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…
}
Tengo dos preguntas sobre esto:
- ¿Está esto cuerdo? Estoy comprobando específicamente el dominio de error y el código de error, y obtengo la cadena de URL de userInfo. ¿Es probable que eso permanezca?
- Esto funciona para el enlace de la tienda de aplicaciones anteriormente vinculado, pero cuando vuelvo a mi aplicación, parece haber una solicitud fallida posterior que falló con la "Carga de cuadro interrumpida". ¿Cómo puedo deshacerme de eso? No sucede cuando el sistema operativo maneja la solicitud desde
-webView:shouldStartLoadWithRequest:navigationType:
así que es un poco molesto.
¿Cómo manejas esas solicitudes?
¿Le ayuda si registra su aplicación para manejar itms: enlaces?
por ejemplo, http://inchoo.net/iphone-development/launching-application-via-url-scheme/
Puede comenzar con el esquema http
pero luego obtener un redireccionamiento de itms
, que podría fallar si su aplicación no está registrada como responsable de ese esquema.
Comenzando con el código de Theory, examine la URL para esquema (s) "itms" (este método puede ser llamado varias veces debido a redirecciones). Una vez que vea un esquema de "itms", detenga la carga de webView y abra la URL con Safari. Mi WebView pasa a estar en un NavigationController, así que salgo de eso después de abrir Safari (menos flasheo).
- (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;
}
}
Esto es lo que se me ocurrió. En webView:shouldStartLoadWithRequest:navigationType:
le pido al sistema operativo que maneje cualquier solicitud que no sea http o que no sea https, como así:
- (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;
}
Esto funciona muy bien, excepto por el sangriento error "Frame Load Interrupted". Pensé que al devolver falso desde webView:shouldStartLoadWithRequest:navigationType:
que la vista web no cargaría la solicitud y, por lo tanto, no habría errores que manejar. Pero a pesar de que devuelvo NO
arriba, sigo con el error de "Frame Load Interrupted". ¿Porqué es eso?
De todos modos, supongo que se puede ignorar en -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…
}
Y ahora las URL de iTunes funcionan correctamente, al igual que los mailto:
s y los enlaces de la aplicación.