Many, if not most, web services have a rate limit for clients. Delicious says a client can make one request per second; Twitter has limits per end-point; I’m sure Facebook and Flickr and Foursquare have their own idea.
You can easily limit an iOS application to a single request at a time using an NSOperationQueue.
But how do you limit an application to making, say, only one request per second?
I’ve looked at the sample code by Apple, AFNetworking, ASINetwork and a few others, and none seem to solve this problem. This seems odd to me. I’ll concede that I could be missing something very obvious…
Some parameters:
- Assume I have an
NSOperationQueuefor network operations and the request is anNSOperation(could also be a GCD queue I suppose, but this is what I’ve mostly been working with) - The same rate limit is used for each request in the queue
- I’m looking for a solution in iOS, but general ideas might be useful
Possible solutions:
sleepstatement in theNSOperation(it’s a queue/thread so this wouldn’t block anything else)NSTimerin theNSOperationperformSelector:in theNSOperation(I patched ASINetworking to use this approach, though I’m not using it and didn’t push the change upstream)- Start/stop the queue (using KVO?) to make sure the rate limit is not exceeded
- Special “sleep”
NSOperation. This would be a task that the next network operation would be dependent upon - Completely ignore the rate limit and just pause a bit when you get the “exceeded rate limit” error response
These all seem quite messy. Operations that sleep would likely prevent forms of “priority” queue. Starting/stopping the queue seems fragile. Ignoring the limit is rude.
To be clear, I have solved this problem. But the solution seems “messy” and somewhat fragile. I’d like to know if there’s a better, cleaner option.
Ideas?
and in your async callback