NSURLSessionDownloadTask - 在 didFinishDownloading 之前读取下载的数据

Posted

技术标签:

【中文标题】NSURLSessionDownloadTask - 在 didFinishDownloading 之前读取下载的数据【英文标题】:NSURLSessionDownloadTask - read downloaded data before didFinishDownloading 【发布时间】:2014-08-23 12:52:03 【问题描述】:

我试图用NSURLSession 替换NSURLConnection,但我发现使用NSURLSession 我无法像在NSURLConnection 中那样使用委托方法读取中间数据块。

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

我曾经在完成之前开始使用数据。我有点流媒体。如何在NSURLSession 完成之前访问下载的数据?

我注意到有一个(NSURL *)location 是在完成之前从NSURLSession 临时保存的数据位置,但是我可以在完成之前获得这个 URL 吗?

谢谢


按照 Rob 的建议进行了尝试:

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue mainQueue]];
NSURLSessionTask *task = [session dataTaskWithRequest:request];
[task resume];

但是,只调用了 didRecieveResponse

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler

但没有调用 didReceiveData。

我尝试将任务更改为downloadTask

NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate:self delegateQueue: [NSOperationQueue mainQueue]];
NSURLSessionDownloadTask * downloadTask =[defaultSession downloadTaskWithRequest:request];
[downloadTask resume];

它适用于下载委托,但未调用数据委托 (didReceiveData)。

谁能告诉我我做错了什么?

【问题讨论】:

【参考方案1】:

如果您使用 NSURLSession 的基于委托的再现,NSURLSessionDataDelegate 协议包含 didReceiveData 方法,因此您可以实例化 NSURLSessionDataTask,然后编写自己的流式处理代码,就像使用 @ 一样987654325@:

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self];
NSURLSessionTask *task = [session dataTaskWithRequest:request];
[task resume];

或者,如果您不想编写自己的流式传输代码,但希望 NSURLSession 为您将其流式传输到文件并让您随时了解其进度,请再次使用基于 delegate 的 @ 再现987654329@,创建和resumeNSURLSessionDownloadTask

NSURLSessionTask *task = [session downloadTaskWithRequest:request];
[task resume];

完成后,您可以实现NSURLSessionDownloadDelegate 协议的didWriteData 方法,它会在数据写入时通知您(显然,只要您的应用程序在前台;如果您使用后台会话并且该应用程序未处于活动状态,您的应用程序仅在所有后台任务完成后才会重新激活)。但这样您就可以两全其美,NSURLSession 会进行流式下载,但会让您随时了解其进度。

但是,如果您使用的是NSURLSessionDownloadTask,则在下载完成之前,您无法访问临时文件的NSURL(在didFinishDownloadingToURL 中,您可以将此临时文件移至其永久最终文件位置)。

【讨论】:

感谢 Rob 的快速回复。听起来很不错,我不知道我可以使用 dataTask 下载文件。让我尝试使用 didReceiveData 委托方法并回复您。非常感谢 嗨,Rob,我尝试了又尝试,但无法正常工作。请你看看我的编辑,看看我做错了什么。谢谢。 @user1256663 您是否称completionHandler 阻止didReceiveResponse 提供给您?我知道我第一次使用基于委托的NSURLSession 时完全忽略了这个关键参数:在调用完成块之前它不会继续。每当这些委托方法中的任何一个提供完成块(接收响应、接收挑战、处理重定向)时,您必须调用它。 就是这样!谢谢罗布。我拉头发这么久了。 再次感谢 Rob。我只是在搜索同一个主题,你写的一切都是正确的。不幸的是,dataTask 不能在后台运行(downloadTask 可以)......所以任何阅读这篇文章的人都要小心这个:)

以上是关于NSURLSessionDownloadTask - 在 didFinishDownloading 之前读取下载的数据的主要内容,如果未能解决你的问题,请参考以下文章

NSURLSessionDownloadTask 进度回调不顺畅?

在 NSMutableDictionary 中设置 NSURLSessionDownloadTask

NSUrlSessionDownloadTask - 进入后台时出现didCompleteWithError

iOS开发之网络编程--2NSURLSessionDownloadTask文件下载

NSURLSessionDownloadTask 在挂起时继续下载

在下载字节时从 NSURLSessionDownloadTask 访问字节