如何使用AFNetworking 2批量请求?

时间:2013-10-16 21:43:49

标签: ios afnetworking afnetworking-2

所以我用AFNetworking 2.0重写iOS 7的应用程序,我遇到了一次发送一批请求并跟踪进度的问题。在旧的AFNetworking中enqueueBatchOfHTTPRequestOperations:progressBlock:completionBlock:上有AFHTTPClient方法,这显然已被重构,我对如何排队多个请求感到困惑。

我创建了AFHTTPSessionManager的子类,我正在使用POST:...GET:...方法与服务器进行通信。但我无法在代码和/或文档中找到任何内容,可以像使用旧的AFHTTPClient一样将多个请求排入队列。

我唯一能找到的是batchOfRequestOperations:progressBlock:completionBlock:上未记录的AFURLConnectionOperation方法,但这看起来像iOS 6的方式。

显然,我错过了新的NSURLSession概念,我应该用它来批量请求或查看新的AFNetworking功能。希望有人能帮助我走上正轨!

tl; dr:如何使用AFHTTPSessionManager子类发送一批请求?

5 个答案:

答案 0 :(得分:85)

感谢Sendoa链接到GitHub issue where Mattt explains,为什么此功能不再有效。有一个明确的原因,为什么新的NSURLSession结构无法做到这一点;任务不是操作,因此使用依赖关系或批量操作的旧方法将无法工作。

我使用dispatch_group创建了此解决方案,可以使用NSURLSession批量处理请求,这里是(伪)代码:

// Create a dispatch group
dispatch_group_t group = dispatch_group_create();

for (int i = 0; i < 10; i++) {
    // Enter the group for each request we create
    dispatch_group_enter(group);

    // Fire the request
    [self GET:@"endpoint.json"
       parameters:nil
          success:^(NSURLSessionDataTask *task, id responseObject) {
                  // Leave the group as soon as the request succeeded
                  dispatch_group_leave(group);
          }
      failure:^(NSURLSessionDataTask *task, NSError *error) {
                  // Leave the group as soon as the request failed
                  dispatch_group_leave(group);
              }];
}

// Here we wait for all the requests to finish
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    // Do whatever you need to do when all requests are finished
});

我想写一些东西,这使得这更容易做,并与Matt讨论,如果这是(很好地实现)可以合并到AFNetworking的东西。在我看来,用图书馆本身做这样的事情会很棒。但是我必须检查一下我有空余时间。

答案 1 :(得分:3)

刚刚更新线程......我遇到了同样的问题,经过一些研究后我发现了一些很好的解决方案,但我决定坚持这个:

我正在使用名为Bolts的项目。因此,对于@ Mac_Cain13发布的上述相同示例,它将是:

[[BFTask taskWithResult:nil] continueWithBlock:^id(BFTask *task) {
    BFTask *task = [BFTask taskWithResult:nil];
    for (int i = 0; i < 10; i++) {
        task = [task continueWithBlock:^id(BFTask *task) {
            return [self executeEndPointAsync];
        }];
    }
    return task;
}] continueWithBlock:^id(BFTask *task) {
    // Everything was executed.
    return nil;
}];;

- (BFTask *) executeEndPointAsync {
    BFTaskCompletionSource *task = [BFTaskCompletionSource taskCompletionSource];
    [self GET:@"endpoint.json" parameters:nil
      success:^(NSURLSessionDataTask *task, id responseObject) {
        [task setResult:responseObject];
      }
      failure:^(NSURLSessionDataTask *task, NSError *error) {
        [task setError:error];
      }];
    }];
    return task.task;
}

基本上,它正在堆叠所有任务,等待和解包,直到没有更多的任务,并且在完成所有任务后,执行最后一个完成块。

另一个做同样事情的项目是RXPromise,但对我来说Bolts中的代码更清晰。

答案 2 :(得分:3)

对于可以requestpost的{​​{1}},您可以使用get进行批量操作,因为首先您需要创建如下操作:

AFNetworking 2.0

现在执行这样的批处理操作:

//Request 1
NSString *strURL = [NSString stringWithFormat:@"your url here"];
NSLog(@"scheduleurl : %@",strURL);
NSDictionary *dictParameters = your parameters here
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" URLString:strURL parameters:dictParameters error: nil];

AFHTTPRequestOperation *operationOne = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operationOne = [AFHTTPResponseSerializer serializer];

[operationOne setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
{
     //do something on completion
} 
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
     NSLog(@"%@",[error description]);
}];

//Request 2
NSString *strURL1 = [NSString stringWithFormat:@"your url here"];
NSLog(@"scheduleurl : %@",strURL);
NSDictionary *dictParameters1 = your parameters here
NSMutableURLRequest *request1 = [[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" URLString:strURL1 parameters:dictParameters1 error: nil];

AFHTTPRequestOperation *operationTwo = [[AFHTTPRequestOperation alloc] initWithRequest:request1];
operationTwo = [AFHTTPResponseSerializer serializer];

[operationTwo setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject)
{
     //do something on completion
} 
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
     NSLog(@"%@",[error description]);
}];

//Request more here if any

答案 3 :(得分:1)

在AFNetworking 2.0上,AFHTTPClient已在AFHTTPRequestOperationManagerAFHTTPSessionManager上分开,因此您可能可以从第一个operationQueue属性开始。

答案 4 :(得分:1)

目前,NSURLSession任务不适合请求操作使用的相同类型的模式。请参阅Mattt Thompson here关于此问题的答案。

直接回答:如果您需要依赖关系或批处理,您仍需要使用请求操作。