How to batch request with AFNetworking 2?

So, I’m rewriting an application for iOS 7 with AFNetworking 2.0, and I ran into the problem of sending a packet of requests right away and tracking their progress. In the old AFNetworking, there was enqueueBatchOfHTTPRequestOperations:progressBlock:completionBlock: method on the AFHTTPClient , this is explicitly refactored, and I'm a bit confused about how to insert multiple requests.

I created a subclass of AFHTTPSessionManager , and I use the POST:... and GET:... methods to communicate with the server. But I can not find anything in the code and / or documents in order to embed several requests at the same time, as with the old AFHTTPClient .

The only thing I can find is the undocumented method batchOfRequestOperations:progressBlock:completionBlock: on AFURLConnectionOperation , but it looks like iOS 6's way of doing this.

Obviously, I'm missing something in the new NSURLSession concept, which I should use for batch requests or viewing the new AFNetworking feature. Hope someone can help me on the right track here!

tl; dr: How to send a request package with my subclass AFHTTPSessionManager ?

+49
ios afnetworking afnetworking-2
Oct 16 '13 at
source share
5 answers

Thanks to Sendoa for the link to the GitHub question, where Matt explains why this functionality no longer works. There is a clear reason why this is not possible with the new NSURLSession structure; Tasks are simply not operations, so the old way of using dependencies or batches of operations will not work.

I created this solution using dispatch_group , which allows batch requests using NSURLSession , here is the (pseudo) code:

 // 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 }); 

I want to see something that will simplify the work and discuss with Matt if it is something (when implemented beautifully) that can be combined into AFNetworking. In my opinion, it would be great to do something similar with the library itself. But I have to check when I have free time.

+84
Nov 09 '13 at 21:35
source share

Just updating the thread ... I had the same problem, and after some research, I found some good solutions, but I decided to stick with this:

I am using a project called Bolts . So, for the same sample above published by @ Mac_Cain13, this would be:

 [[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; } 

Basically, he stacks all the tasks, waits and unfolds until there are more tasks, and after everything is completed, the last block of completion will be completed.

Another project that does the same is RXPromise, but for me the more understandable Bolts code.

+3
Dec 09 '14 at 7:41
source share

For request , which can be post or get , you can use AFNetworking 2.0 for packet control, since you need to create an operation as follows:

 //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 

Now do the batch operation as follows:

 //Batch operation //Add all operation here NSArray *operations = [AFURLConnectionOperation batchOfRequestOperations:@[operationOne,operationTwo] progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) { NSLog(@"%i of %i complete",numberOfFinishedOperations,totalNumberOfOperations); //set progress here yourProgressView.progress = (float)numberOfFinishedOperations/(float)totalNumberOfOperations; } completionBlock:^(NSArray *operations) { NSLog(@"All operations in batch complete"); }]; [[NSOperationQueue mainQueue] addOperations:operations waitUntilFinished:NO]; 
+3
May 20 '15 at 7:01
source share

In AFNetworking 2.0, AFHTTPClient was split into AFHTTPRequestOperationManager and AFHTTPSessionManager , so maybe you can start with the first one that has the operationQueue property.

+1
Nov 05 '13 at 2:16
source share

NSURLSession tasks are NSURLSession not suitable for the same type of template request operations. See Answer from Mattt Thompson here regarding this issue.

The direct answer is: if you need dependencies or parties, you still have to use query operations.

+1
Nov 05 '13 at 10:22
source share



All Articles