Ios 使用AFNetworking 2.0上载进度
我知道这个问题在这个网站上非常流行,但是在搜索了大部分答案后,我找不到解决方案。 我的应用程序是将图像上传到远程url。我尝试了几种上传方式,都成功了:Ios 使用AFNetworking 2.0上载进度,ios,objective-c,Ios,Objective C,我知道这个问题在这个网站上非常流行,但是在搜索了大部分答案后,我找不到解决方案。 我的应用程序是将图像上传到远程url。我尝试了几种上传方式,都成功了: (1) 使用AFURLSessionManager AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
(1) 使用AFURLSessionManager
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[(AFHTTPResponseSerializer*)manager.responseSerializer setAcceptableContentTypes:[NSSet setWithObjects:@"multipart/form-data", nil]];
NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithStreamedRequest:request progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
NSDictionary *userInfo=[error userInfo];
id responseError=[userInfo objectForKey:@"AFNetworkingOperationFailingURLResponseErrorKey"];
if ([responseError isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *reponse=(NSHTTPURLResponse*)responseError;
if (reponse.statusCode==200) {
result(YES);
} else {
result(NO);
}
} else {
result(NO);
}
} else {
result(YES);
}
}];
[uploadTask resume];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
AFHTTPRequestOperation *operation =
[manager HTTPRequestOperationWithRequest:request
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"Success %@", responseObject);
result(YES);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (operation.response.statusCode==200) {
result(YES);
} else {
result(NO);
}
}];
// 4. Set the progress block of the operation.
[operation setUploadProgressBlock:^(NSUInteger __unused bytesWritten,
long long totalBytesWritten,
long long totalBytesExpectedToWrite) {
double percentDone = (double)totalBytesWritten / (double)totalBytesExpectedToWrite;
NSLog(@"progress updated(percentDone) : %f", percentDone);
}];
// 5. Begin!
[operation start];
对于这种方式,我使用KVO来监控进度,但没有运气
(2) 使用AFHTTPRequestOperation
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
NSLog(@"total bytes written: %lld",totalBytesWritten);
}];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
result(YES);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (operation.response.statusCode==200) {
result(YES);
} else {
result(NO);
}
}];
[operation start];
它仅显示日志“total bytes Writed:”仅一次,在开始上载时立即显示文件的100%卷
(3) 使用AFHTTPRequestOperationManager
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[(AFHTTPResponseSerializer*)manager.responseSerializer setAcceptableContentTypes:[NSSet setWithObjects:@"multipart/form-data", nil]];
NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithStreamedRequest:request progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
NSDictionary *userInfo=[error userInfo];
id responseError=[userInfo objectForKey:@"AFNetworkingOperationFailingURLResponseErrorKey"];
if ([responseError isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *reponse=(NSHTTPURLResponse*)responseError;
if (reponse.statusCode==200) {
result(YES);
} else {
result(NO);
}
} else {
result(NO);
}
} else {
result(YES);
}
}];
[uploadTask resume];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
AFHTTPRequestOperation *operation =
[manager HTTPRequestOperationWithRequest:request
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"Success %@", responseObject);
result(YES);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (operation.response.statusCode==200) {
result(YES);
} else {
result(NO);
}
}];
// 4. Set the progress block of the operation.
[operation setUploadProgressBlock:^(NSUInteger __unused bytesWritten,
long long totalBytesWritten,
long long totalBytesExpectedToWrite) {
double percentDone = (double)totalBytesWritten / (double)totalBytesExpectedToWrite;
NSLog(@"progress updated(percentDone) : %f", percentDone);
}];
// 5. Begin!
[operation start];
=>第二个解决方案的结果相同
请注意,所有解决方案均已成功上载,但进度未更新(
NSProgress
或block)。在NSProgress上设置观察者
差不多
[uploadTask resume];
[progress addObserver:self
forKeyPath:@"fractionCompleted"
options:NSKeyValueObservingOptionNew
context:NULL];
然后实施
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"fractionCompleted"]) {
NSProgress *progress = (NSProgress *)object;
NSLog(@"progress = %f", progress.fractionCompleted);
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
上传任务完成后,别忘了删除观察者
注意:progress.fractionCompleted返回一个百分比值。最后,我找到了进度块没有被调用的原因:我上传了一个大约几十Kb的非常小的图像。我尝试上传更大的文件,进程块被调用。根据我的经验,KVO和NSProgress不起作用。相反,我们可以使用AFHTTPRequestOperation或AFHTTPRequestOperationManager。如果您喜欢手动上传,您可以按照建议使用NSURLConnection和委派方法:
-(void)连接:(NSURLConnection*)连接
didSendBodyData:(NSInteger)字节写入
TotalBytesWrited:(NSInteger)TotalBytesWrited
totalBytesExpectedToWrite:(集成器)totalBytesExpectedToWrite{
NSLog(@“百分比:%d”,100*TotalBytesWrite/totalBytesExpectedToWrite);
}
than,但我在项目中使用了上述代码(KVO Key-value observer)。我不知道为什么观察员没有开火。我按照u的建议上传了一个更大的文件,代理连接:didSendBodyData被调用,日志也被打印出来。但是1)委托中的self.uploadProgress为零,因此不会调用回调块setUploadProgressBlock。2) AFURLConnectionOperation.m中的调试描述了self.uploadProgressBlock在委托中变为nil时具有内容的self.uploadProgress。