简答:
使用UIWebViewDelegate 方法shouldStartLoadWithRequest 并不是一个很好的机制来确定您将被重定向到哪个站点(特别是因为从您的代码判断,您最终将在外部应用程序中打开它,而不是您的@ 987654324@),因为在重定向发生之前你得到了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 来跟踪重定向,但我们并不真正关心我们通常使用NSURLConnection 检索的responseData,我们可以在您取消连接后立即取消连接收到良好的响应(确信我们已经知道最终重定向到了哪个站点):
- (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);
}
最后,值得指出的是,这种使用 NSURLConnection 发出 HTTP 请求并让它跟随整个重定向系列的技术是一个非常低效的过程,因此您必须决定是否值得.但这是确定您的 HTTP 重定向将引导您到哪里的一种方法。
最后一个警告,这捕获了传统的重定向,但如果页面正在执行任何客户端 JavaScript 重定向,我认为这种技术不会起作用。不过,它适用于绝大多数重定向的 HTTP 请求。