Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

beginBackgroundTaskWithExpirationHandler calling endBackgroundTask but not ending process

I have some long running process which I want to run even if application goes in background. I am calling application's beginBackgroundTaskWithExpirationHandler: method and in the expirationBlock I am calling application's endBackgroundTask. Here is the implementation:

__block UIBackgroundTaskIdentifier task = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
    [[UIApplication sharedApplication] endBackgroundTask:task];
    task = UIBackgroundTaskInvalid;
}];
dispatch_queue_t queue = dispatch_queue_create("com.test.test1234", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
    // My Task goes here
});

In some cases, my serial queue have more task to perform which can not be completed within the time provided by system. So expiration block will execute and in that I am ending the UIBackgroundTaskIdentifier but not stopping the dispatch process (I can't even cancel a dispatch).

Apple's document says:

Each call to the beginBackgroundTaskWithName:expirationHandler: or beginBackgroundTaskWithExpirationHandler: method generates a unique token to associate with the corresponding task. When your app completes a task, it must call the endBackgroundTask: method with the corresponding token to let the system know that the task is complete. Failure to call the endBackgroundTask: method for a background task will result in the termination of your app. If you provided an expiration handler when starting the task, the system calls that handler and gives you one last chance to end the task and avoid termination.

So, according to this if I doesn't call the endBackgroundTask: my app will be terminated, which is ok.

My question is: with my current implementation what if I call endBackgroundTask: in expirationHandler block and my dispatch queue's task doesn't get complete? My app will be terminated or will be suspended?

thanks

like image 787
Kapil Choubisa Avatar asked Apr 28 '15 12:04

Kapil Choubisa


2 Answers

Here are some scenario, which you need to handle while using beginBackgroundTaskWithExpirationHandler otherwise your app will terminate.

Scenario 1 : Your app is running in Foreground. you are start beginBackgroundTaskWithExpirationHandler then enter in Background mode. your app keep alive for long.

Scenario 2 : Your app is running in Foreground. you are start beginBackgroundTaskWithExpirationHandler then enter in Background mode. Then come back to Foreground mode and you are not calling endBackgroundTask then your application still execute background queue so it will extent that process for next 3 minute (After IOS 7 introduce. before IOS 7, the process execution time was 10 minute). so you must need to cancel background queue and task come out from background queue and enter in foreground queue.

So here are the code that show you. what is best way handle background process.

Step 1: Declare __block UIBackgroundTaskIdentifier bgTask as global variable.

Step 2: To add following code in applicationDidEnterBackground.

- (void)applicationDidEnterBackground:(UIApplication *)application {

         bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
         bgTask = UIBackgroundTaskInvalid;
          }];

}

Step 3: Stop background task handler once apps come in foreground mode.

- (void)applicationWillEnterForeground:(UIApplication *)application {
  // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.

  [[UIApplication sharedApplication] endBackgroundTask:bgTask];

}
like image 119
Jatin Patel - JP Avatar answered Oct 04 '22 09:10

Jatin Patel - JP


If you don't call endBackgroundTask in your expiration handler, your app will be terminated.

Once you call endBackgroundTask in your expiration handler, you are only telling the OS "OK, I'm done with saving critical tasks. It's up to you now." After that your app may be suspended for a while and terminated later, or it may be terminated immediately depending on the system resources.

like image 21
John Estropia Avatar answered Oct 04 '22 10:10

John Estropia