公司舊項目的網絡請求類是afn 2.5版本的,在做文件上傳的時候發現沒有實時獲取進度的那個自帶方法,需要手動添加。
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSProgress *progress = nil;
//2.5版本的afn這里progress只傳入一個對象的地址,不像后來的版本是個block可以獲取進度
NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithStreamedRequest:request progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
[IBTLoadingView hideHUDWithText:nil];
NSLog(@"Error: %@", error);
fail(error);
} else {
[IBTLoadingView hideHUDWithText:nil];
NSLog(@"%@ %@", response, responseObject);
succ(responseObject);
}
}];
[uploadTask resume];
//1. 添加觀察者,監視進度條變化。 progress的fractionCompleted屬性就是當前的進度
[progress addObserver:self
forKeyPath:@"fractionCompleted"
options:NSKeyValueObservingOptionNew
context:NULL];
調用觀察者的方法
我們假設當前類(在例子中為UITableViewController)還有父類,并且父類也有自己綁定了一些其他KVO呢?我們看到,上述回調函數體中只有一個判斷,如果這個if不成立,這次KVO事件的觸發就會到此中斷了。但事實上,若當前類無法捕捉到這個KVO,那很有可能是在他的superClass,或者super-superClass...中,上述處理砍斷了這個鏈。合理的處理方式應該是這樣的
#pragma mark - 拿到文件上傳進度
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
//拿到進度
if ([keyPath isEqualToString:@"fractionCompleted"] && [object isKindOfClass:[NSProgress class]]) {
NSProgress *progress = (NSProgress *)object;
NSLog(@"Progress is %f", progress.fractionCompleted);
//進度到1的時候說明加載完成了,移除觀察者
//不知道這么寫對不對,有人發現不對請指出來,非常感謝~
if (progress.fractionCompleted == 1) {
[progress removeObserver:self forKeyPath:@"fractionCompleted"];
}
}else{
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}