4

我有一个用 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”协议或类似的东西。

4

1 回答 1

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子类,将其设置为某个合理的数字(4 或 5),就像查看 AFNetworking 代码一样,它似乎并没有这样做。我发现,如果您超出此范围,则收益会递减,并且如果所有文件都来自单个服务器,则给定客户端和给定服务器之间可以执行多少并发操作会受到限制。operationQueueHTTPClient

  • 我读过传闻称苹果将拒绝通过蜂窝网络提出特殊请求的应用程序。请参阅https://stackoverflow.com/a/14922807/1271826

于 2013-03-01T17:16:39.783 回答