applicationDidEnterBackground is not waiting till method execution is completed

794 views Asked by At

I would like to save data when app goes in background. I am doing cancelling NSOperation and saving data in applicationDidEnterBackground. But it does not complete execution.

How can I complete this before my app goes in background?

Code :

-(void)applicationDidEnterBackground:(UIApplication *)application

{

    //FUNCTION_START
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.

    [self performSelectorOnMainThread:@selector(dispatchStateNotification:)
                           withObject:[NSNumber numberWithInt:666]
                        waitUntilDone:YES ];

    // Write to core data
    GWSCoreDataController *dataController = [GWSCoreDataController sharedManager];

    NSError *error;
    if (![dataController.managedObjectContext save:&error]) {
        NSLog(@"Error while saving data to Core Data: %@", [error localizedDescription]);
    }

   // FUNCTION_END

}

-(void)dispatchStateNotification:(NSNumber *)value {
    [[NSNotificationCenter defaultCenter] postNotificationName:APPLICATION_ENTERED_BACKGROUND_NOTIFICATION object:value];

}
3

There are 3 answers

0
iAsh On BEST ANSWER

I have solved this problem for my requirement like below. Added one flag and run while loop till this flag will not become false. As soon as my task will get complete or app comes in foreground I have marked this flag as false.

     // start the task asynchronously which is written into the block on new thread.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{

    //this loop runs continuously while flag is YES.
    while(appDidEnterBackground){
        sleep(1);
    }//end of while

    //ends the background task.
    [application endBackgroundTask: background_task];
    background_task = UIBackgroundTaskInvalid;

});//end of dispatch queue
0
l0gg3r On

You can start a background task, and do your cleanup stuff

- (void)applicationDidEnterBackground
{
    UIBackgroundTaskIdentifier bgTaskId =
    [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        [[UIApplication sharedApplication] endBackgroundTask:bgTaskId];
    }];

    // Start cleanup
    .......
    [[UIApplication sharedApplication] endBackgroundTask: bgTaskId];
}
0
hyouuu On

I had the same issue and had to put the save call in applicationWillResignActive instead - didEnterBackground just doesn't seem to have the complete CoreData to save with...