2

I have a class that sends webservice calls and delivers the response via delegation. I now want to add a caching layer in between the views and my webservice class. This new class should serialize the calls in a way that every call is delayed until the callback of the previous call has finished.

I tried to realize that with GCD:

- (void)callWebserviceFunctionX {
    dispatch_group_notify(self.serviceGroup, self.serialQueue, ^{
        dispatch_group_enter(self.serviceGroup);

        // call webservice
    });
}

And in the callback:

-(void)callbackFunctionXWithResponse:(id)response {
    // do something

    dispatch_group_leave(self.serviceGroup);
}

The idea to group each call and its callback with dispatch_group_enterand dispatch_group_leave and wait for previous groups using dispatch_group_notify.

However, this approach does not seem to work as I intended. Is there a better way to achieve this?

UPDATE:
I tried every combination of dispatch_group_enter, dispatch_group_leave, dispatch_group_notifyand dispatch_group_async I can think of without success.
I also thought about NSOperationand NSOperationQueue, but - if I understood correctly - that would force me to write a separate class for every webservice call.

Is there another alternative I did not think of yet?

dsolimano
  • 8,870
  • 3
  • 48
  • 63
cLar
  • 280
  • 1
  • 3
  • 17

2 Answers2

2

You could use MKNetworkKit as your Networking solution. This uses NSOperationQueue under the hood and you can use NSOperation dependencies to serialize your request / responses. MKNetworkKit also supports caching of the responses so might help with your caching implementation also.

MKNetworkKit Overview
http://blog.mugunthkumar.com/products/ios-framework-introducing-mknetworkkit/

Someone had a similar problem using MKNetworkKit and GCD
MKNetworkKit and GCD dispatch_group_t

Community
  • 1
  • 1
Fergal Rooney
  • 1,330
  • 2
  • 18
  • 31
2

I think you'd be better off using NSOperation, dependencies between them to ensure serialisation and NSOperationQueue to run them.

To avoid creating a NSOperation subclass for each request you could use the builtin NSBlockOperation, you provide a block to each instance and adding dependencies between the NSBlockOperation instances should give you the aimed serialisation.

Hope this helps.

Regards

Carlos
  • 2,883
  • 2
  • 18
  • 19
  • Thanks!I chose this answer over the first one because it does not include a third party framework and avoids a ton of subclasses by using `NSBlockOperation`. – cLar Nov 04 '14 at 15:42
  • I'm using a solution like this successfully. I've also added operationQueue.isSuspended = true at the start of each block and operationQueue.isSuspended = false in the completionBlock of the asynchronous web service that runs in each block. Also with operationQueue.maxConcurrentOperationCount = 1 This allows my queue to be serialized and also to stop processing when encountering an error so that appropriate recovery can take place. – jcpennypincher Aug 29 '18 at 15:28