1

I'm using AFNetworking's AFHTTPClient class to communicate with a Rails backend.

When creating objects, I want to run several API calls on the server using a batch API (I'm using batch_api in case you were wondering).

To nicely extend AFHTTPClient I was thinking of having an API that would look like this:

[[[SPRRailsClient] sharedInstance] batchOperations:^ {
    NSMutableURLRequest *request = [[SPRRailsAPIClient sharedClient]
                  requestWithMethod:@"GET"                                                                                                       
                               path:myPath
                         parameters:parameters];
    AFHTTPRequestOperation *operation = [[SPRRailsAPIClient sharedClient]
                          HTTPRequestOperationWithRequest:request
                                                  success:nil
                                                  failure:nil];

}];

The trick would be to override SPRRailsClient (my AFHTTPClient subclass) so when requestWithMethod:path:parameters: and HTTPRequestOperationWithMethod:success:failure: are called within a batchOperations block if behaves in a different way (queues things, or reruns a different subclass of AFOperation.

The neat thing of this design is that it would allow me to keep existing code and only wrap it within the block in order for some calls to be executed in "batch mode".

My question is: how can I detect that a method is being called from a block? I need requestWithMethod:path:parameters: to detect that, and:

  1. If called from a batchOperations block, behave in a different way.
  2. If not called from a batchOperations block just call super.

I know it would be simpler to just add two additional methods to SPRRailsClient, but I thought this looked better.

Also, I figure it's possible, since some methods of UIView animations behave in a different way when called from within an animation block, and NSManangedObjectContext's performBlock: is probably doing something similar as well.

pgb
  • 24,813
  • 12
  • 83
  • 113

1 Answers1

1

The only way I can think of would be to enqueue the batchOpperations blocks on a named queue, then check the queue name when executing the blocks. This would look something like:

In the top of your .m file, or in your method, either works.

static dispatch_queue_t myQueue;

Then within batchOpperations,

if (!myQueue){
 myQueue = dispatch_queue_create("com.mydomain.myapp.myqueue", NULL);
}

dispatch_async(myQueue, batchOpperation);

Then within when your sharedClient methods are called, check the queue:

if ([[NSString stringWithCString:dispatch_queue_get_label(dispatch_get_current_queue()) encoding:NSUTF8StringEncoding] isEqualToString:@"com..."]){
    something....
} 
else{
    [super ??];
}
Adam Shiemke
  • 3,734
  • 2
  • 22
  • 23