首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSProgress fractionCompleted键值观察方法未被调用

NSProgress fractionCompleted键值观察方法未被调用
EN

Stack Overflow用户
提问于 2014-02-10 11:28:19
回答 3查看 7.5K关注 0票数 10

我正在尝试使用AFNetworking和NSProgress跟踪我的HTTP请求的进度。基本上,我的请求是一个包含文本参数和图像数据的多部分表单数据,都在一个块中。

这是我上传任务的代码,在我看来很简单,也很正常:

代码语言:javascript
复制
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];

现在,我不明白的是,即使上传任务完成并成功,回调观察者方法也不会被调用。谁能帮我弄明白原因吗?这是我的密码。

代码语言:javascript
复制
- (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属性。如何在不直接修改NSProgress代码的情况下对这个新的AFNetworking实例进行键值观察?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-02-10 14:59:03

我放弃了从AFURLSessionManager中跟踪进度的方法。相反,我使用了一个好的旧AFHTTPRequestOperation

代码语言:javascript
复制
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];
票数 5
EN

Stack Overflow用户

发布于 2014-04-14 17:13:55

好吧,你所需要做的就是在上传任务创建之后,移动你的观察者,它会像一个魅力一样工作。

代码语言:javascript
复制
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];
票数 7
EN

Stack Overflow用户

发布于 2015-07-13 16:03:50

您可能会遇到这个问题,https://github.com/AFNetworking/AFNetworking/issues/1398,这实际上是由于NSURLSession中的设计限制。在讨论接近尾声的时候,您将看到一个建议的解决办法。我正在使用这个解决方法,观察"fractionCompleted“对我来说很好。

-brian

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21675934

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档