使用 AFNetworking 下载大文件

Posted

技术标签:

【中文标题】使用 AFNetworking 下载大文件【英文标题】:Downloading large files with AFNetworking 【发布时间】:2012-11-03 08:14:14 【问题描述】:

我正在尝试实现大文件的下载并向用户显示当前进度,但阻止:

-[AFURLConnectionOperation setDownloadProgressBlock:] 

返回不正确的 bytesReadtotalBytesRead 值(它们小于应有的值)。

例如:如果我有一个 90MB 的文件,当它完全下载时,setDownloadProgressBlock: 中的最新块调用给了我大约 30MB 的 totalBytesRead 值。另一方面,如果文件是 2MB 大,最新的块调用会给出正确的 totalBytesRead 2MB 值。

AFNetworking 已从 github 更新到最新版本。 如果 AFNetworking 无法正确执行,我可以使用什么解决方案?

编辑:我已经确定即使文件没有完全下载(并且每次文件相对较大时都会发生这种情况)AFNetworking 调用成功块:

-[AFHTTPRequestOperation setCompletionBlockWithSuccess:failure:]

我就这种情况向here 提出了类似的问题,但没有得到任何答案。 我可以检查下载的代码和实际文件大小,但AFNetworking 没有用于继续部分下载的 API。

【问题讨论】:

试用github.com/steipete/AFDownloadRequestOperation 也支持恢复部分下载 谢谢,但由于某种原因,它对我不起作用。 【参考方案1】:

我对 AFNetworking 中的 setDownloadProgressBlock 没有任何问题。

wiki 解释了如何跟踪下载进度: https://github.com/AFNetworking/AFNetworking/wiki/AFNetworking-FAQ

对于进度跟踪,您不需要 bytesRead(特定回调中写入的字节数)。

示例代码:

[downloadoperation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) 
        float progress = ((float)totalBytesRead) / totalBytesExpectedToRead;
        self.progressView.progress = progress;
    ];

【讨论】:

是的,我明白了,我的代码和你的一样。我只是说 bytesRead 在大文件上也给出了不正确的数字。 你能举个例子吗?正如我所说,您可以忽略bytesRead,因为它与进度无关。 NSLog(@"%u %llu %llu", bytesRead, totalBytesRead, totalBytesExpectedToRead); 有什么好处? bytesRead 在每个回调中应该或多或少相同。 我在我的问题中添加了一个示例来澄清它。如果我对每个块调用 bytesRead 求和,它将给出等于 totalBytesRead 的值,换句话说就是不正确的值。 AFNetworking 做对了,看源码:github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/… 显然连接取消太早了,可能是磁盘空间不够。我假设您已经设置了一个写入文件的 NSOutputStream。否则会消耗大量内存,ios 可能会因此取消下载。【参考方案2】:

phix23回答了我最初的问题,所以进度块确实没有问题。我正在回答我的编辑。

当成功阻塞时

-[AFHTTPRequestOperation setCompletionBlockWithSuccess:failure:]

被调用,我可以将下载的字节数与预期下载的字节数进行比较(在代码中实现起来并不难)。如果下载的字节数较小 - 我可以从中断的地方继续下载文件。为此,我在NSURLRequest 中使用了Range http 标头,这里有更多信息:Continue an interrupted download on iPhoneHow to implement resumable file downloads on iPhone SDK

因此,问题并不在于 AFNetworking(NSURLConnection 具有相同的行为),但我认为框架的开发人员可以考虑这种情况。

【讨论】:

~goodfella "我可以将下载的字节数与预期下载的字节数进行比较。(在代码中实现起来并不难)。" 你能用代码详细说明一下吗?您如何获得预期的字节数?我无法从 AFNetworking 中找到这样的 API 您可以在以下类中找到示例代码:github.com/onivem/Download,尤其是在 setCompletionBlocks 方法中。请注意,这个类是为 AFNetworking 编写的,因为它是在 2013 年 5 月。

以上是关于使用 AFNetworking 下载大文件的主要内容,如果未能解决你的问题,请参考以下文章

IOS AFN (第三方请求)

使用 AFNetworking 下载大文件

iOS开发之AFN的基本使用

AFN2.0到3.0的迁移

如何使用 AFNetworking 3.0 在后台下载大文件并在会话完成所有任务时显示本地通知

AFN3.0封装