简短的回答:
使用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-years.html?hp&_r=0
第三次调用shouldStartLoadWithRequest
是我定义bit.ly
重定向 URL 的实际 URL,即两个连续重定向的最终目的地。但是,如果您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 重定向将引导您到哪里的一种方法。
One final caveat, this captures traditional redirects, but if the page is doing any client-side JavaScript redirects, I don't think this technique will work. It works for the vast majority of redirected HTTP requests, though.