【发布时间】:2014-03-07 17:01:11
【问题描述】:
我正在尝试使用 AFNetworking 和 NSProgress 跟踪我的 HTTP 请求的进度。基本上,我的请求是一个包含文本参数和图像数据的多部分表单数据。
这是我的上传任务代码,对我来说似乎很简单和正常:
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"<THE_API_URL>" parameters:nil constructingBodyWithBlock:constructionBlock];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
NSProgress *progress = [[NSProgress alloc] initWithParent:nil userInfo:nil];
[progress addObserver:self forKeyPath:@"fractionCompleted" options:NSKeyValueObservingOptionNew context:NULL];
NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithStreamedRequest:request progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
// UI reacts to error
} else {
// Do stuff here
}
}];
[uploadTask resume];
现在,我不明白的是,即使上传任务完成并成功,回调观察者方法也没有被调用。有人可以帮我理解为什么吗?这是我的代码。
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
if ([keyPath isEqualToString:@"fractionCompleted"] && [object isKindOfClass:[NSProgress class]]) {
NSProgress *progress = (NSProgress *)object;
NSLog(@"Progress is: %f", progress.fractionCompleted);
}
}
更新:我遵循 AFNetworking 的 uploadTaskWithStreamedRequest:... 方法代码,发现它们实际上是从 uploadTaskWithTask:... 内部替换我的 NSProgress 对象。自然,如果NSProgress 指针指向一个新实例,则该新实例不会注册以观察fractionCompleted 属性。如何在不直接修改 AFNetworking 代码的情况下对这个新的 NSProgress 实例进行键值观察?
【问题讨论】:
-
fractionCompleted 是只读的,所以我怀疑它是在 completedUnitCount 更改时计算的......所有这些都意味着 fractionCompleted 可能是不可观察的。也许如果你尝试观察 completedUnitCount 呢?
-
恐怕它是可观察到的,如 NSProgress 文档中所述:
Each of the properties of a progress object, including totalUnitCount, completedUnitCount, and fractionCompleted, support Key-Value Observing. -
@merlevede 同意。我调查了
AFURLSessionManagerTaskDelegate来源。代码仅更改completedUnitCount属性。 -
我按照 AFNetworking 的
uploadTaskWithStreamedRequest:...方法代码,发现它们实际上是从uploadTaskWithTask:...内部替换我的 NSProgress 对象。自然,如果 NSProgress 指针指向一个新实例,则该新实例不会注册以观察fractionCompleted属性。如何在不直接修改 AFNetworking 代码的情况下对这个新的 NSProgress 实例进行键值观察? -
您的问题实际上帮助我以不同的方式看待问题并解决了我一直坚持一段时间的问题:完全覆盖 UIProgressView 可以正常使用 NSProgress(又名 .observedProgress)。你的问题让我想起了关于 NSProgress 的 WWDC 2015 会议以及 WWDC 面包屑和你的问题,bam,我有 real 循环进度视图,现在可以基于简单地更新 completedUnitCount aka 来进行各种绘图和动画
theProgress.completedUnitCount += 1;代码中的其他地方。如果可以的话,我会为你投 10 次赞成票。
标签: ios iphone objective-c ipad cocoa-touch