Search code examples
objective-ccocoa-touchgrand-central-dispatchlong-running-processes

GCD and UIBackgroundTaskIdentifier


I have a dispatch queue that has some work in it. I want the queue to keep running till either time runs out or the queue gets drained, when the application goes into the background. How would I set up the UIBackgroundTaskIdentifier?

Do I need to put it into the dispatch block like so?

    dispatch_async(queue, ^{
        if (_bgTask == UIBackgroundTaskInvalid) {
            if ([UIDevice currentDevice].multitaskingSupported) {
                _bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^(void) {
                    if (_bgTask != UIBackgroundTaskInvalid) {
                        [[UIApplication sharedApplication] endBackgroundTask:_bgTask];
                        _bgTask = UIBackgroundTaskInvalid;
                    }
                }];
            }
        }

...
...

        if (_bgTask != UIBackgroundTaskInvalid) {
                    [[UIApplication sharedApplication] endBackgroundTask:_bgTask];
                    _bgTask = UIBackgroundTaskInvalid;
                }

            });

I think what happens in the above is it isn't registered as a long running task till the queue actually runs the block. So do I need to place the backgrounding portion of the code outside the block, so that it executes prior to being actually queued up?


Solution

  • I am not sure why you are keeping track of the UIBackgroundTaskID in what I assume is an ivar. The easiest way to do this is:

    UIBackgroundTaskIdentifier btid = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{...}];
    dispatch_async(queue, ^{
        ... // Your code...
        [[UIApplication sharedApplication] endBackgroundTask:btid];
    }