Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS Background Task Completion Programming

I'm trying to add support for completing a task after exiting the foreground for my iOS App. All the tutorials I saw on the internet point me to writing something like this in the Application Delegate:

- (void)applicationDidEnterBackground:(UIApplication *)application {
    if ([[UIDevice currentDevice] isMultitaskingSupported]) {
        UIApplication *application = [UIApplication sharedApplication];
        __block UIBackgroundTaskIdentifier background_task;
        background_task = [application beginBackgroundTaskWithExpirationHandler: ^ {
            [application endBackgroundTask: background_task];
            background_task = UIBackgroundTaskInvalid;
        }];

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

            //DO STUFF IN BACKGROUND HERE
            MyTask *task = [[MyTask alloc] initWithURL:@"http://google.com"];
            [task setDelegate:self];
            [task start];

            [application endBackgroundTask: background_task];
            background_task = UIBackgroundTaskInvalid;
        });
    }
}

The task is able to start, but after it starts, the next line gets processed and my app is killed. I am able to tell when MyTask stops due to a delegate call, but how do I change my program so that the background task gets set to invalid after the delegate gets called. Would I move

[application endBackgroundTask: background_task];
background_task = UIBackgroundTaskInvalid;

to the delegate function, or do I need to do something else.

Thanks in advance for your help, Guvvy

like image 501
Gavy Avatar asked Mar 09 '26 01:03

Gavy


1 Answers

You're already in a background thread per your call to dispatch_async. That method will return immediately, but your block will continue to run.

Your problem seems to be that your start method runs another asynchronous process, so that method returns immediately, and your background task is killed before [task start] is able to do anything meaningful.

If you go the route of killing background_task in your delegate, you'll also have to create an ivar to store background_task so your delegate methods can get to it. That seems a little heavy handed.

Since you're already in a background thread, my suggestion would be for you to refactor [task start] so it's synchronous. That way, all the meaningful work will be performed before the next line is processed and background_task is killed. This seems cleaner, and everything for your background task is nicely wrapped in the block sent to dispatch_async.

like image 195
djibouti33 Avatar answered Mar 10 '26 15:03

djibouti33



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!