【问题标题】:xcode, nslog weird hitchxcode,nslog 奇怪的故障
【发布时间】:2013-03-12 20:24:51
【问题描述】:

当单击 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]];
}

【问题讨论】:

  • 你是说如果你去掉这个方法的第二行,你得到的结果与第一行不同?你能提供一些我们可以运行的代码来演示这个问题吗?
  • 是的,代码应该贴在上面。只需尝试将 Web 视图链接到具有位 URL 的站点。
  • 要对此进行测试,必须创建一个带有 Web 视图的完整应用程序。你一定已经做了一些自己的测试——包括最小化代码——试图解决这个问题,所以分享一下结果。
  • 我认为问题是 UIAPPLICATION 在请求 url 完全读取它之前打开。有没有办法阻止这种情况?

标签: iphone ios objective-c xcode


【解决方案1】:

简答:

使用UIWebViewDelegate 方法shouldStartLoadWithRequest 并不是一个很好的机制来确定您将被重定向到哪个站点(特别是因为从您的代码判断,您最终将在外部应用程序中打开它,而不是您的@ 987654324@),因为在重定向发生之前你得到了shouldStartLoadWithRequest。不过,您可以使用NSURLConnectionNSURLConnectionDataDelegate 方法来确定您最终会被重定向到哪里。

长答案:

如果您查看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 肯定会返回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 来跟踪重定向,但我们并不真正关心我们通常使用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 请求。

【讨论】:

  • 噢……好答案,你救了我! +1
猜你喜欢
  • 2012-06-07
  • 2012-02-22
  • 1970-01-01
  • 1970-01-01
  • 2020-08-03
  • 1970-01-01
  • 2019-11-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多