[英]NSProgress fractionCompleted key-value observing method not called
我正在嘗試使用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
對象uploadTaskWithTask:...
當然,如果使NSProgress
指針指向新實例,則不會注冊該新實例以觀察fractionCompleted
屬性。 如何在不修改AFNetworking代碼的情況下對此新NSProgress
實例進行鍵值觀察?
所有你需要做的就是將你的觀察者移動到創建上傳任務之后,它將像魅力一樣工作。
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];
我放棄了這種從AFURLSessionManager
跟蹤進度的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];
您可能遇到此問題, https://github.com/AFNetworking/AFNetworking/issues/1398 ,這實際上是由於NSURLSession中的設計限制。 在討論結束時,您將看到建議的解決方法。 我正在使用這種解決方法,觀察“fractionCompleted”對我來說很好。
布賴恩
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.