簡潔な答え:
UIWebViewDelegate
メソッドを使用することは、リダイレクトshouldStartLoadWithRequest
されるサイトを特定するための優れたメカニズムではありません (特に、コードから判断すると、最終的には ではなく外部アプリで開くことになるUIWebView
ため)。shouldStartLoadWithRequest
起こる。ただし、NSURLConnection
およびNSURLConnectionDataDelegate
メソッドを使用して、最終的にリダイレクトされる場所を特定することはできます。
長い答え:
を見てshouldStartLoadWithRequest
、 を返せば、 にリダイレクト リクエストをフォローYES
させることができます。UIWebView
次のことを考慮してくださいshouldStartLoadWithRequest
。
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSLog(@"%@", request.URL);
return YES;
}
これをランダムなbit.ly
URL、たとえば で使用するとhttp://nyti.ms/Yi6EAk
、次のログが表示されます。
2013-03-12 21:23:31.418 webtest[6959:c07] http://nyti.ms/Yi6EAk
2013-03-12 21:23:31.511 webtest[6959:c07] http://bit.ly/Yi6EAk?cc=0d7134b272b1004cb954d0400076e9fa
2013-03-12 21:23:31.560 webtest[6959:c07] http://www.nytimes.com/2013/03/13/us/politics/ryans-plan-aims-to-balance-budget-in- 10年.html?hp&_r=0
3 番目の への呼び出しshouldStartLoadWithRequest
は、リダイレクト URL を定義した実際の URL ですbit.ly
。つまり、2 つの連続するリダイレクトの最終的な宛先です。しかし、shouldStartLoadWithRequest
が返された場合、NO
最終的にどのサイトにリダイレクトされるかはわかりません。(ちなみに、あなたshouldStartLoadWithRequest
は間違いなく戻ってくるべきです.YES
またはNO
...あなたのサンプルも返されません.)
ご覧のとおりshouldStartLoadWithRequest
、リダイレクトが行われる前に発生するため、すべてのリダイレクトが行われていることがわかります。shouldStartLoadWithRequest
結果のサイトの動作によっては、ページが余分なコンテンツを取得するときに、後続の呼び出しが表示される場合があります。これにより、最終的にリダイレクトされたサイトを見つけるための厄介なメカニズムになります.
リダイレクト先のサイトが本当に必要な場合はNSURLConnection
、代わりに , を使用することをお勧めします。これは通常、サーバーから実際にデータを取得するために使用されますが、リダイレクトをキャプチャするためにも使用できます (ただし、ページにランダムに追加されたコンテンツと本物のリダイレクトを区別するのが難しいUIWebViewDelegate
メソッドの問題はありません)。shouldStartLoadWithRequest
後で要求する場合があります)。
したがって、次のことを考慮してください。
self.url = [NSURL URLWithString:@"http://nyti.ms/Yi6EAk"];
NSURLRequest *request = [NSURLRequest requestWithURL:self.url];
[NSURLConnection connectionWithRequest:request delegate:self];
次に、さまざまなリダイレクトを追跡connection:willSendRequest:redirectResponse:
するメソッドである を実装できます。NSURLConnectionDataDelegate
- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response
{
self.url = request.URL;
return request;
}
明らかに、あなたはリダイレクトを追跡するために使用していますが、私たちは通常、取得に使用する をNSURLConnection
あまり気にしていないため、適切な応答を受信したらすぐに接続をキャンセルできます (どのサイトは最終的にリダイレクトされました):responseData
NSURLConnection
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[connection cancel];
NSLog(@"Ok, we now know that the resulting URL is %@", self.url);
}
ちなみに、次のような接続エラーもキャプチャする必要がある場合があります。
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"Ok, we failed trying to retrieve data from %@", self.url);
}
最後に、HTTP リクエストを作成し、NSURLConnection
一連のリダイレクト全体を追跡させるこの手法は、かなり非効率的なプロセスであることを指摘しておきます。そのため、それが価値があるかどうかを判断する必要があります。しかし、これは HTTP リダイレクトがどこにつながるかを把握するための 1 つの方法です。
最後の警告として、これは従来のリダイレクトをキャプチャしますが、ページがクライアント側の JavaScript リダイレクトを実行している場合、この手法は機能しないと思います。ただし、リダイレクトされた HTTP リクエストの大部分では機能します。