ios - AFNetworking 2.0 如何获取下载进度?

标签 ios objective-c afnetworking-2

我正在使用 AFURLSessionManager 创建一个新的下载任务:

AFURLSessionManager* manager = ...

NSProgress* p = nil;
NSURLSessionDownloadTask* downloadTask =
        [manager downloadTaskWithRequest:request
                                 progress:&p
                              destination:^NSURL*(NSURL* targetPath, NSURLResponse* response) {...}
                        completionHandler:^(NSURLResponse* response, NSURL* filePath, NSError* error) {...}
        ];
[downloadTask resume];

文件下载正常,但是我如何获得进度通知?

p 始终设置为 nil。我已经提交了 issue为此。

我还尝试在管理器上调用 setDownloadTaskDidWriteDataBlock,我确实在那里收到了进度通知,但在文件下载完成后 我收到了所有这些通知。

似乎这个区域在 AFNetworking 2.0 中还是有点问题

有什么想法吗?

最佳答案

您应该使用 KVO 观察 NSProgress 对象的 fractionCompleted 属性:

NSURL *url = [NSURL URLWithString:@"http://www.hfrmovies.com/TheHobbitDesolationOfSmaug48fps.mp4"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPSessionManager *session = [AFHTTPSessionManager manager];
NSProgress *progress;
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request progress:&progress destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
    // …
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
    [progress removeObserver:self forKeyPath:@"fractionCompleted" context:NULL];
    // …
}];

[downloadTask resume];
[progress addObserver:self
            forKeyPath:@"fractionCompleted"
               options:NSKeyValueObservingOptionNew
               context:NULL];

然后添加观察者方法:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"fractionCompleted"]) {
        NSProgress *progress = (NSProgress *)object;
        NSLog(@"Progress… %f", progress.fractionCompleted);
    } else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

当然,您应该检查 keyPath 和/或 object 参数来确定这是否是您要观察的对象/属性。

您还可以使用 AFURLSessionManager(AFHTTPSessionManager 继承)中的 setDownloadTaskDidWriteDataBlock: 方法来设置接收下载进度更新的 block 。

[session setDownloadTaskDidWriteDataBlock:^(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) {
    NSLog(@"Progress… %lld", totalBytesWritten);
}];

此 AFNetworking 方法将 URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite: 方法从 NSURLSessionDownloadDelegate 协议(protocol)映射到更方便的 block 机制。

顺便说一句,Apple 的 KVO 实现被严重破坏了。我建议使用更好的实现,例如 Mike Ash 提出的 MAKVONotificationCenter。 .如果您有兴趣了解 Apple 的 KVO 为何损坏,请阅读 Key-Value Observing Done Right迈克·阿什 (Mike Ash)。

关于ios - AFNetworking 2.0 如何获取下载进度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19145093/

相关文章:

php - 用户名和密码参数的 AFNetworking 异步 POST 请求(Objective-C iOS)

ios - Swift 3 中的不安全指针

ios - 尝试解开 Realm 对象时出错

ios - 呈现 SecondViewController 时重复调用 ViewDidAppear

ios - 如何将类属性与枚举匹配?

ios - 如何在 AFNetworking 中获取状态码

ios - 使用 NSUTF8StringEncoding 将 NSData 转换为 NSString 对于特殊字符不起作用

objective-c - UISegementSwitch 不工作

objective-c - Cocoa 多值 bool 绑定(bind),使用逻辑 OR

validation - AFNetworking 2.0有效证书,仍然无法连接(错误1012)