我已经阅读了大量的消息,再次说同样的事情:当你使用NSURLConnection时,委托方法不被称为。我理解Apple的文档是不完整的,并且引用了弃用的方法,这是一种耻辱,但我似乎无法找到解决方案。
请求代码在那里:
// Create request
NSURL *urlObj = [NSURL URLWithString:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:urlObj cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30];
[request setValue:@"gzip" forHTTPHeaderField:@"Accept-Encoding"];
if (![NSURLConnection canHandleRequest:request]) {
NSLog(@"Can't handle request...");
return;
}
// Start connection
dispatch_async(dispatch_get_main_queue(), ^{
self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]; // Edited
});
...委托方法的代码在这里:
- (void) connection:(NSURLConnection *)_connection didReceiveResponse:(NSURLResponse *)response {
NSLog(@"Receiving response: %@, status %d", [(NSHTTPURLResponse*)response allHeaderFields], [(NSHTTPURLResponse*) response statusCode]);
self.data = [NSMutableData data];
}
- (void) connection:(NSURLConnection *)_connection didFailWithError:(NSError *)error {
NSLog(@"Connection failed: %@", error);
[self _finish];
}
- (void) connection:(NSURLConnection *)_connection didReceiveData:(NSData *)_data {
[data appendData:_data];
}
- (void)connectionDidFinishDownloading:(NSURLConnection *)_connection destinationURL:(NSURL *) destinationURL {
NSLog(@"Connection done!");
[self _finish];
}
这里没有很多错误检查,但我确定了一些事情:
didReceiveData
从不被调用,所以我没有得到任何数据tcpdump
)NSURLConnectionDownloadDelegate
代替NSURLConnectionDataDelegate
,一切正常,但我无法保留下载的文件(这是一个已知错误)我不想使用第三方库,因为最终,这些请求将包含在我自己的库中,并且我希望最小化依赖项。如果必须的话,我会直接使用CFNetwork
,但在你知道什么的情况下,这将是一个巨大的痛苦。
如果您有任何想法,那将会有很大帮助。谢谢!
答案 0 :(得分:13)
我遇到了同样的问题。非常讨厌,但似乎如果你实现这个方法:
- (void)connectionDidFinishDownloading:(NSURLConnection *)connection destinationURL:(NSURL *)destinationURL
然后永远不会调用connection:didReceiveData:
。您必须使用connectionDidFinishLoading:
代替...是的,文档说它已被弃用,但我认为这仅仅是因为此方法已从NSURLConnectionDelegate
移至NSURLConnectionDataDelegate
。
答案 1 :(得分:2)
我喜欢使用sendAsynchronousRequest方法..连接过程中信息较少,但代码更清晰。
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
if (data){
//do something with data
}
else if (error)
NSLog(@"%@",error);
}];
来自Apple:
默认情况下,会在当前线程上安排连接 创建时的默认模式。如果您创建了一个连接 initWithRequest:delegate:startImmediately:方法并为其提供NO startImmediately参数,您可以在a上安排连接 使用start方法启动之前的不同运行循环或模式。 您可以在多个运行循环和模式上安排连接,也可以安装 多种模式下的相同运行循环。
除非有理由在[NSRunLoop currentRunLoop]中明确运行它, 你可以删除这两行:
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[connection start];
或将模式更改为NSDefaultRunLoopMode
答案 2 :(得分:1)
NSURLConnection API说“..线程上的..delegate方法被称为,它启动了相关NSURLConnection对象的异步加载操作。”
因为dispatch_async将启动新线程,并且NSURLConnection不会传递回另一个威胁,所以不要将dispatch_async 与NSURLConnection一起使用。
您不必担心冻结的用户界面,NSURLConnection只提供异步加载的控件。
如果你有要下载的文件,你可以在第一回合开始一些连接,之后他们就完成了,在connectionDidFinishLoading:方法中你可以开始新的连接。
int i=0;
for (RetrieveOneDocument *doc in self.documents) {
if (i<5) {
[[NSURLConnection alloc] initWithRequest:request delegate:self];
i++;
}
}
..
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
ii++;
if(ii == 5) {
[[NSURLConnection alloc] initWithRequest:request delegate:self];
ii=0;
}
}
答案 3 :(得分:0)
一个可能的原因是,传出的NSURLRequest
已设置为-HTTPMethod
HEAD
。虽然很难做到这一点!