theDuncs
theDuncs

Reputation: 4843

Cancel background task when app enters foreground

In my app I am syncing my data with the server when a user closed the app (i.e. it enters the background). This process takes about a minute and involves various calls to the server to upload data, so I am choosing to perform it as a background thread.

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

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

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [asynchronousAPIController processQueueOrWaitWithIsBackgroundSync:true];

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

This works fine, unless a user re-enters the foreground during this sync (i.e. during that first minute). What I want is for the background sync to terminate completed - stop syncing even if it's midway through it's sync. When the app next goes into the background, it can restart the whole process from scratch, no problem.

I've tried using this:

- (void)applicationWillEnterForeground:(UIApplication *)application {
    if (bgTask != UIBackgroundTaskInvalid) {
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }
}

But it doesn't stop the syncing - that just keeps going. Almost as if once it's started it just keeps going.

I'm suspicious that it might be because the object controlling the sync is a Singleton - i.e. instead of being a class object which could just be destroyed, it's a singleton and so might be staying alive for that reason. Could that make a difference?

Or am I just doing something wrong?

Any advice, much appreciated.

Upvotes: 2

Views: 2325

Answers (1)

Felix
Felix

Reputation: 35384

You will need to do the background work in a NSOperation. I would create a NSBlockOperation and add it to a NSOperationQueue. That way a background thread is spawned automatically. For complex operations create a NSOperation subclass. Inside the NSOperation code check if the operation is cancelled regularly (for example inside a for loop) and exit the the code block if yes (in the for loop: if ([operation isCanceled]) break;). In applicationWillEnterForeground just cancel the operation.

Upvotes: 4

Related Questions