1

When you create/update/delete a record in my app it creates an OutgoingRequest in Core Data. Periodically, the app will get these requests in a queue, and push them all to the server. I do this using a AFHTTPClient post (seen below). The issue I am running into is that it pushes all of these requests up at one time, then the responses come back in no real order.

What I need to do is make these requests work 'synchronically' in that request B should not be posted until request A has finished (success or fail response). This is done in the background as well, and should not hang the UI.

for(OutgoingRequest *req in queue)
{
    NSURL *reqUrl = [NSURL URLWithString: globals.baseURL];
    AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:reqUrl];
    [httpClient setParameterEncoding:AFJSONParameterEncoding];

    NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
                            req.url, @"viewName",
                            req.json, @"JSON",
                            req.dateAdded.description, @"dateTime",
                            nil];

    NSString *path = [NSString stringWithFormat:@"cache/update/?deviceUID=%@&token=%@", [MySingleton getMacAddress],  globals.token];

    [httpClient postPath:path parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {

            //handle the repsonse

        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

    }];
}

Is there any way to achieve this with my current setup? Or should I be using other means to POST to my server?

Thanks

RyanG
  • 4,393
  • 2
  • 39
  • 64

2 Answers2

1

Probably the best idea here is to use AFHTTPRequestOperation (or one of it subclasses) and create a dependencies between them: 2 op. depends on 1 op., 3 op. depends on 2 op. and so on...

Please take a look to AFNetworking and NSOperation documentation (AFHTTPRequestOperation is a subclass of NSOperation).

Vytautas
  • 573
  • 3
  • 8
1

I'd recommend that you look at the internal NSOperationQueue that the AFHTTPClient manages. You can set the maxConcurrentOperationCount to 1 to make it a serial queue, thus your requests will execute one at a time in the order you add them to the queue.

This is the readonly operationQueue property on AFHTTPClient.

/**
The operation queue which manages operations enqueued by the HTTP client.
*/
@property (readonly, nonatomic, strong) NSOperationQueue *operationQueue;

Wherever you do your client setup, set the concurrent operation count to 1.

myHTTPClient.operationQueue.maxConcurrentOperationCount = 1;

With regards to network requests, a serial queue is probably a good idea anyway. At the end of the day, the number of concurrent requests are still rate limited by the number of HTTP connections you can have open with your server, and the bandwidth of the devices antenna, both of which have an upper limit.

Drewsmits
  • 1,384
  • 2
  • 14
  • 24
  • Any advantage of setting this property vs using dependencies as Vytautas recommended? I ended up doing as he said, and it seems to be working as I wanted. Still testing though – RyanG Nov 01 '13 at 17:50
  • I'd recommend to you stick with dependencies. It gives you correct results, and it also maintains an ability to make multiple request at the same time. What is really good thing. – Vytautas Nov 04 '13 at 15:12
  • Dependencies will definitely work and are a good option in this case. However, depending on your implementation, you may be using them to mask a design flaw. I've found that using a serial queue prevents a whole class of concurrency bugs from even existing in the first place. If you manage your requests properly, the user won't even notice a performance hit. If you do stuff like download images as well, you can maintain two queues; One serial queue for downloading and modifying resources, another concurrent for downloading images. – Drewsmits Nov 04 '13 at 16:19