Mat*_*ros 9 iphone cocoa-touch objective-c ipad ios
我正在尝试使用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];
Run Code Online (Sandbox Code Playgroud)
现在,我不明白的是,即使上传任务完成并成功,也不会调用回调观察者方法.有人可以帮我理解为什么吗?这是我的代码.
- (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);
}
}
Run Code Online (Sandbox Code Playgroud)
更新:我遵循AFNetworking的uploadTaskWithStreamedRequest:...方法代码,发现它们实际上是NSProgress从内部替换我的对象uploadTaskWithTask:....当然,如果NSProgress指针指向新实例,则不会注册该新实例以观察该fractionCompleted属性.如何在NSProgress不修改AFNetworking代码的情况下对此新实例进行键值观察?
所有你需要做的就是将你的观察者移动到创建上传任务之后,它将像魅力一样工作.
NSProgress *progress;
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];
[progress addObserver:self forKeyPath:@"fractionCompleted" options:NSKeyValueObservingOptionNew context:NULL];
Run Code Online (Sandbox Code Playgroud)
我放弃了这种跟踪进度的方法AFURLSessionManager.相反,我用了一个好老AFHTTPRequestOperation.
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"THE_API_URL" parameters:nil constructingBodyWithBlock:constructionBlock];
AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperationManager manager] HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
// Do stuff here
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// Catch error
}];
[requestOperation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
double percentDone = (double)totalBytesWritten / (double)totalBytesExpectedToWrite;
progressBlock(percentDone);
}];
[requestOperation start];
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6497 次 |
| 最近记录: |