如何使用AFNetworking并行请求并收集所有结果

时间:2016-07-07 12:28:14

标签: ios objective-c afnetworking

我的场景是这样的,首先我有一个服务器json api,它返回指定页面的一些数据,api就像/data/page/1。对于这种情况,假设响应数据是:

page 1 => ['a','b']
page 2 => ['c','d']
page 3 => ['e','f']

我使用AFNetworking 2从api获取数据,对于单页数据请求它运行良好。

问题是现在我想为多个页面实现并行请求。我需要一个api用于接受一个页码的视图控制器,并回收所有这些页面的数据。我需要的是:

typedef void (^DataBlock)(id data);

- (void) dataForPages:(NSInteger)pages withSuccessBlock:(DataBlock)block;

如果视图控制器为3参数传递pages,我希望AFNetworking可以并行请求数据,然后收集3结果,然后在回调块中使用。

我尝试使用NSOperationQueue处理多个AFHTTPRequestOperation但失败了,代码演示是这样的:

- (void) dataForPages:(NSInteger)pages withSuccessBlock:(DataBlock)block
{

    //want to use for each, here suppose pages is 3

    NSMutableArray *result = [[NSMutableArray alloc] init];

    AFHTTPRequestOperation  *op1 = [[AFHTTPRequestOperation alloc] initWithRequest:@"/data/page/1"];
    AFHTTPRequestOperation  *op2 = [[AFHTTPRequestOperation alloc] initWithRequest:@"/data/page/2"];
    AFHTTPRequestOperation  *op3 = [[AFHTTPRequestOperation alloc] initWithRequest:@"/data/page/3"];


    [op1 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        [result addObjectsFromArray: responseObject];    //responseObject is ['a', 'b']
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    }];

    [op2 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        [result addObjectsFromArray: responseObject];    //responseObject is ['c', 'd']
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    }];

    [op3 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        [result addObjectsFromArray: responseObject];    //responseObject is ['e', 'f']
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    }];


    NSOperationQueue *q = [[NSOperationQueue alloc] init];

    [q addOperation:op1];
    [q addOperation:op2];
    [q addOperation:op3];


    [q waitUntilAllOperationsAreFinished];


    block(result);
}

在我的测试中结果总是空的,我不太明白waitUntilAllOperationsAreFinished

任何人都知道如何使用NSOperationGCD处理此问题?

1 个答案:

答案 0 :(得分:0)

经过一些代码研究后,我发现很难通过NSOperationNSOperationQueue获得我想要的内容,因为AFNetworking拥有它自己的completion block handler

最终解决方案是使用dispatch_group,所有代码都是这样的:

dispatch_group_t group = dispatch_group_create();


NSURLRequest *req1 = ...;
NSURLRequest *req2 = ...;

AFHTTPRequestOperation  *op1 = [[AFHTTPRequestOperation alloc] initWithRequest:req1];
AFHTTPRequestOperation *op2 = [[AFHTTPRequestOperation alloc] initWithRequest:req2];

NSMutableArray *result = [[NSMutableArray alloc] init];

dispatch_group_enter(group);     //enter group

[op1 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    [result addObjectsFromArray: responseObject];
    dispatch_group_leave(group);      //leave group in completion handler
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    dispatch_group_leave(group);
}];

dispatch_group_enter(group);
[op2 setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    [result addObjectsFromArray: responseObject];
    dispatch_group_leave(group);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    dispatch_group_leave(group);
}];

[op1 start];
[op2 start];

dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    block(result);
});