簡體   English   中英

NSProgress fractionCompleted鍵值觀察方法未調用

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM