I have found several post asking how to run background tasks. This is fine. I get it. There is a guideline from Apple and can be done only for certain types of Apps.
My use case here is the following: I want to update the contact list of a chat App only when the APP is in foreground. Hence I can start/pause/resume when the App goes respectively in the following states: didBegan, didEnterBackground, didResumeFromBackground.
How can I achieve this using GCD?
In other words, how can I schedule an asynchrounous task in a repeated way and to be called only every so often (say every 0.5 seconds)? Is there a good implementation using NSOperationQueue?
EDIT 2: Tasks I want to perform:
1: GET from a webservice API a JSON data object containing information on the contacts (online status, device, lastseen at)
2: GET from a webservice API a JSON data object containing messages to the user
EDIT: NSOperation documentation defines an operation as something that can be used only as "single shot", hence creating a recursive operation is probably not the best way to solve this.
Here is some code on how to achieve this with a timer and both GCD and an operation queue.
NSOperationQueue* queue = [NSOperationQueue new];
[queue setMaxConcurrentOperationCount:1]; //Make serial.
//dispatch_queue_t queue = dispatch_queue_create("queue", NULL); //Serial queue.
Gentlemen, start your timers:
[NSTimer scheduledTimerWithTimeInterval:0.0 target:appDelegate selector:@selector(timerTicked:) userInfo:nil repeats:NO]; //Start a timer with 0 so it ticks immediately.
Now in the method:
- (void)timerTicked:(NSTimer*)timer
{
NSLog(@"Timer ticked!");
void (^block)() = ^{
//Do what you need here.
//Start a new timer.
[NSTimer scheduledTimerWithTimeInterval:1.0 target:appDelegate selector:@selector(timerTicked:) userInfo:nil repeats:NO];
};
[queue addOperationWithBlock:block];
//dispatch_async(queue, block);
}
I use the app delegate because timers retain the target object, so I don't want to have it in a view controller. You can schedule the next timer either right after timer tick or after the operation/task has completed, which is what I prefer to do.