Comment gérer les URL d'application dans un UIWebView?

J'ai récemment trouvé que mon UIWebView s'étouffait sur les liens d'ITMS. Plus précisément, à partir de l'UIWebView dans mon application, si je navigue vers un site comme celui-ci et que je clique sur le lien "Disponible sur l'App Store", UIWebView commettrait une erreur avec "Error Domain = WebKitErrorDomain Code = 101 L'URL ne peut pas être montré. "

Après un peu de googling, je me suis rendu count que j'avais besoin d'attraper des requêtes pour les liens d'application et que iOS les gère. J'ai commencé par regarder si le système commençait par "itms" dans -webView:shouldStartLoadWithRequest:navigationType: mais -webView:shouldStartLoadWithRequest:navigationType: réalisé qu'il pourrait y avoir d'autres types de liens d'application que le système peut gérer. Donc je suis venu avec ceci, à la place:

 - (void)webView:(UIWebView *)wv didFailLoadWithError:(NSError *)error { // Give iOS a chance to open it. NSURL *url = [NSURL URLWithSsortingng:[error.userInfo objectForKey:@"NSErrorFailingURLSsortingngKey"]]; if ([error.domain isEqual:@"WebKitErrorDomain"] && error.code == 101 && [[UIApplication sharedApplication]canOpenURL:url]) { [[UIApplication sharedApplication]openURL:url]; return; } // Normal error handling… } 

J'ai deux questions à ce sujet:

  1. Est-ce sain d'esprit? Je vérifie spécifiquement le domaine d'erreur et le code d'erreur et récupère la string d'URL de userInfo. Est-ce que ces choses sont susceptibles de restr?
  2. Cela fonctionne pour le lien de l'App Store ci-dessus, mais lorsque je returnne à mon application, il semble qu'il y ait eu une request échouée qui a échoué avec "Frame load interromped". comment puis-je me débarrasser de cela? Cela ne se produit pas lorsque le operating system gère la requête de -webView:shouldStartLoadWithRequest:navigationType: donc c'est un peu ennuyeux.

Comment gérezvous ces requests?

Voici ce que j'ai trouvé. Dans webView:shouldStartLoadWithRequest:navigationType: je request au operating system de gérer toutes les requêtes non-http et non-https qu'il peut, comme ceci:

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

Cela fonctionne très bien, sauf pour l'erreur sanglante "Frame Load Interrupted". Je pensais qu'en returnnant false de webView:shouldStartLoadWithRequest:navigationType: que la vue web ne chargerait pas la requête et qu'il n'y aurait donc pas d'erreurs à gérer. Mais même si je renvoie NO ci-dessus, j'ai toujours "Frame Load Interrupted" erreur. Pourquoi donc?

Quoi qu'il en soit, je suppose qu'il peut être ignoré dans -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… } 

Et maintenant, les URL iTunes fonctionnent correctement, tout comme mailto: s et les liens d'applications.

En commençant par le code de Theory, examinez l'URL du ou des schémas "itms" (cette méthode peut être appelée plusieurs fois en raison de redirections). Une fois que vous voyez un schéma "itms", arrêtez le chargement de webView et ouvrez l'URL avec Safari. Mon WebView se trouve être dans un NavigationController, donc je sors de cela après l'ouverture de Safari (less clignotant).

 - (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType { if ([[[request URL] scheme] isEqualToSsortingng:@"itms-apps"]) { [webView stopLoading]; [[UIApplication sharedApplication] openURL:[request URL]]; [self.navigationController popViewControllerAnimated:YES]; return NO; } else { return YES; } } 

Cela vous aide-t-il si vous enregistrez votre application pour gérer itms: des liens?

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

Vous pouvez commencer avec le schéma http mais ensuite get une redirection itms , qui pourrait échouer si votre application n'est pas enregistrée comme gérant ce schéma.