我有一个用AFNetworking制作的iOS应用程序。 我有一个单独的自定义httpclient子类,我用它来使用我的api并从服务器下载二进制文件。
我需要下载大约100个文件。通过我的url数组迭代并为每个url创建一个AFHTTPRequestionOperation是否安全?我的代码是这样的:
NSMutableURLRequest* rq = [[MIHTTPClient sharedInstance] requestWithMethod:@"GET" path:@"...." parameters:nil];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:rq] ;
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
//completion
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//manage error
}];
[[MIHTTPClient sharedInstance] enqueueHTTPRequestOperation:operation];
如何从此队列收到反馈?我没有看到任何“HTTPClientDelegate”协议或类似的东西。
答案 0 :(得分:5)
关于进度,请参阅setDownloadProgressBlock
(AFURLConnectionOperation
的一部分,其中AFHTTPRequestOperation
是子类),例如:
[operation setDownloadProgressBlock:^(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite) {
NSLog(@"Sent %d of %d bytes, %@", totalBytesWritten, totalBytesExpectedToWrite, path);
}];
并且,在您的代码示例中,您正在调用setCompletionBlockWithSuccess:failure:
,以便提供有关完成各个操作的状态。就个人而言,在我的小测试中,我只维护了一系列我要求的下载,并且这三个块(进度,成功和失败)更新了我的下载状态代码,如下所示:
for (NSInteger i = 0; i < 20; i++)
{
NSURLRequest *request = ... // set the request accordingly
// create a download object to keep track of the status of my download
DownloadObject *object = [[DownloadObject alloc] init];
download.title = [NSString stringWithFormat:@"Download %d", i];
download.status = kDownloadObjectStatusNotStarted;
[self.downloadObjects addObject:download];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
download.status = kDownloadObjectStatusDoneSucceeded;
// update my UI, for example, I have table view with one row per download
//
// [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:i inSection:0]]
// withRowAnimation:UITableViewRowAnimationNone];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
download.status = kDownloadObjectStatusDoneFailed;
// update UI
//
// [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:i inSection:0]]
// withRowAnimation:UITableViewRowAnimationNone];
}];
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
download.totalBytesRead = totalBytesRead;
download.status = kDownloadObjectStatusInProgress;
// update UI
//
// [self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:i inSection:0]]
// withRowAnimation:UITableViewRowAnimationNone];
}];
[queue addOperation:operation];
}
您可以通过这种方式跟踪各个下载内容。您还可以跟踪待处理的操作(或查询HTTPClient
对象的operationQueue
属性,并查看该属性的operationCount
属性。
在下载100个文件方面,有两个注意事项:
我原以为您要在setMaxConcurrentOperationCount
子类的operationQueue
上调用HTTPClient
,将其设置为合理的数字(4或5),在浏览AFNetworking代码时,它似乎并没有这样做。我发现,如果你远远超过它,那么回报会递减,如果所有文件都来自单个服务器,那么在给定客户端和给定服务器之间可以完成多少并发操作存在约束。
我读过轶事声称Apple会拒绝通过蜂窝网络提出异常请求的应用程序。见https://stackoverflow.com/a/14922807/1271826。