xcode,nslog奇怪的故障

时间:2013-03-12 20:24:52

标签: iphone ios objective-c xcode

下面的代码在点击tinyurl链接时在tinyurl链接上给我一个NSLog重定向位置。但是,如果我删除下面的代码[[UIApplication sharedApplication] openURL:[request URL]];,它将为我提供NSLog中的实际网站,而不是tinyurl链接。如何在显示共享应用程序代码时在NSLog中拥有实际网站URL?

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType  {
    NSLog(@"Redirect Location: %@",[request.URL absoluteString]);
    [[UIApplication sharedApplication] openURL:[request URL]];
}

1 个答案:

答案 0 :(得分:1)

简短回答:

使用UIWebViewDelegate方法shouldStartLoadWithRequest并不是一个很好的机制,可以确定您将被重定向到哪个网站(特别是从您的代码判断,您最终会在外部应用中打开它,而不是您的UIWebView),因为您在重定向发生之前获得shouldStartLoadWithRequest。但是,您可以使用NSURLConnectionNSURLConnectionDataDelegate方法确定最终将重定向的位置。

答案很长:

如果您查看shouldStartLoadWithRequest,如果您返回YES,则会让UIWebView按照重定向请求进行操作。请考虑以下shouldStartLoadWithRequest

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSLog(@"%@", request.URL);
    return YES;
}

如果您使用随机bit.ly网址,例如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重定向网址的实际网址,即两个连续重定向的最终目的地。但是,如果您的shouldStartLoadWithRequest返回NO,那么您将永远无法确定哪个网站最终会被重定向。 (顺便提一下,您的shouldStartLoadWithRequest肯定会返回YESNO ...您的样本也不会返回。)

正如您所看到的,因为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请求并让它遵循整个重定向系列的技术是一个非常低效的过程,所以你必须决定它是否是值得。但这是确定HTTP重定向将引导您的方法的一种方法。

最后一点需要注意,这会捕获传统的重定向,但如果页面正在进行任何客户端JavaScript重定向,我认为这种技术不会起作用。但它适用于绝大多数重定向的HTTP请求。