2010-11-28 83 views
57

私は最近、私のUIWebViewがITMSリンクで窒息していることがわかりました。具体的には、私のアプリケーションのUIWebViewから、this oneのようなサイトに移動し、 "App Storeで利用可能"リンクをクリックすると、UIWebViewは "Error Domain = WebKitErrorDomain Code = 101"でエラーになります。URLは表示できません"UIWebViewでアプリのURLを処理する方法は?

Googleで少し話をしたあと、アプリリンクのリクエストを受け取り、iOSで処理する必要があることに気付きました。私は、スキームが-webView:shouldStartLoadWithRequest:navigationType:の "itms"で始まるかどうかを調べることから始めましたが、システムが処理できる他の種類のアプリリンクがあるかもしれないことに気付きました。だから私が代わりに、この思い付いた:

- (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. は、この正気ですか?私は特に、エラードメインとエラーコードをチェックしていて、userInfoからURL文字列を取得しています。そのものは残っている可能性がありますか?
  2. これは、上記のリンク先のアプリケーションストアリンクでは機能しますが、私のアプリに戻ったときに、「フレーム読み込み中断」で失敗した後続のリクエストが失敗したようです。どうすればそれを取り除くことができますか?私はOSが-webView:shouldStartLoadWithRequest:navigationType:からのリクエストを処理するときには起こらないので、ちょっと面倒です。

あなたはのようなリクエストを処理しますか?

答えて

88

これは私が思いついたものです。

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

これは血まみれの「フレームロード中断」エラーを除いて非常によく動作します:webView:shouldStartLoadWithRequest:navigationType:では、私はそうのように、それができるように要求する任意の非HTTPおよびHTTPS以外を処理するためにOSをお願いします。私はwebView:shouldStartLoadWithRequest:navigationType:からfalseを返すことによって、Webビューが要求をロードしないため、処理するエラーがないと考えていました。しかし、上記の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… 
} 

そしてmailto:のアプリへのリンクがそうであるように、今iTunesのURLは、正常に動作します。

+1

iTunesだけでなく、私もWebビューを通じてFacebookのログインでこれを持っていました。 – Adam

+0

これも私にとって素晴らしい仕事でした。ありがとう! – spstanley

+0

私の一日を保存してくれてありがとう – duan

-2

itms:リンクを処理するためにアプリを登録すると役立ちますか?

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

あなたはスキームhttpで始まるが、その後、あなたのアプリがそのスキームを扱うとして登録されていない場合は失敗する可能性がありitmsリダイレクトを、得ることができます。

+1

私のアプリが 'itms'スキームを扱わないようにしたいと思います。誰かがUIWebViewのリンクをクリックしてビュー自体が処理できないことを知りたいのですが、iOSが対応できるかどうかを確認し、そうであればそれを確認します。自分のアプリにURLスキームを登録しているかどうかは関係ありません。 – theory

+0

URLを見るだけではわかりません。あなたが示したように失敗を処理するのがおそらく最善の方法です。私は "Frame Load Interrupted"がitmsスキームのURLへのリダイレクトから来るかもしれないと思うので、私はあなたのappを有能な人として登録することを提案しました。 –

8

理論のコードから始めて、 "itms"スキームのURLを調べます(このメソッドはリダイレクトのために複数回呼び出すことができます)。 「itms」スキームが表示されたら、WebViewの読み込みを停止し、SafariでURLを開きます。私の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; 
    } 
} 
+0

iOS 6.0ではスキームが「itmss」 – cynistersix

+0

iOS 9ではスキームが「itms-appss」です –

関連する問題