Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

applicationWillTerminate when is it called and when not

Tags:

iphone

ios4

Hi I have read several questions on SO about applicationWillTerminate getting called and not getting called.

I wanted to summarize what I understood as there are several posts that speak differently.

  1. For IOS (without multitasking) it is called always when home button is pressed.

  2. For IOS 4 and above

    a. it is not called when pressing home button (as the app moves to background)

    b. it is called when closing the app from the multi tasking dock and if the app has a sudden terminate flag in info.plist disabled else it is not called. ( I set the "Application should get App Died events" and even then on closing the app from the multitasking dock the terminate function did not get called)

Based on that I had a couple of questions

Is it a good practise to set the Application should get App Died events flag? ( I set the "Application should get App Died events" and even then on closing the app from the multitasking dock the terminate function did not get called)

or

Is registering for "UIApplicationWillTerminateNotification" a better thing to do than the info.plist setting?

Basically I need to do some work only when the app terminates and NOT when it moves to background.

or

EDIT (1): When the app is terminated the following is sent to the APP. How do I catch it?

Program received signal: “SIGKILL”.

EDIT (2):

Please note : It is not getting called in IOS 4 and above when removing from the multitasking dock. You might think it is. But in my case it is not.

I am asking if anyone knows why? Is there something else I am missing.

Also Note I set the "Application should get App Died events" and even then it is not getting called.

EDIT (3):

The answer for the following question also did not work. applicationWillTerminate does not get invoked

Anybody facing the similar issue as me?

like image 575
Anand Avatar asked Oct 19 '11 07:10

Anand


People also ask

When applicationWillTerminate is called?

So, applicationWillTerminate is called when a user terminates the app without switching it to background mode: the app is active, the user makes double press on Home button and throws out the app.

Does background fetch work when app is terminated?

The Background Fetching will NOT happen in your app after the user has killed it in the multitasking UI. This is by design.

What is UIApplication in Swift?

The application object maintains a list of open windows ( UIWindow objects), which it can use to retrieve any of the app's UIView objects. The UIApplication class defines a delegate that conforms to the UIApplicationDelegate protocol and must implement some of the protocol's methods.


3 Answers

In short, unless you have UIApplicationExitsOnSuspend in your Info.plist set to YES, in iOS4 and above there is no guarantee that applicationWillTerminate: will ever get called.

As the documentation says:

For applications that support background execution, this method is generally not called when the user quits the application because the application simply moves to the background in that case. However, this method may be called in situations where the application is running in the background (not suspended) and the system needs to terminate it for some reason

(Emphasis mine.)

If you need to do something before the app exits you need to do it in applicationDidEnterBackground:. There is no way to catch SIGKILL.

like image 167
Stephen Darlington Avatar answered Sep 19 '22 13:09

Stephen Darlington


I see -applicationWillTerminate: getting called with the following test. In a new project (I used the 'Single View Application' template), add the following to the AppDelegate:

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    NSLog(@"%s", __PRETTY_FUNCTION__);

    __block UIBackgroundTaskIdentifier identifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        if (identifier != UIBackgroundTaskInvalid) {
            [[UIApplication sharedApplication] endBackgroundTask:identifier];
            identifier = UIBackgroundTaskInvalid;
        }
    }];

    dispatch_async(dispatch_get_main_queue(), ^{
        for (int i=0; i < 20; i++) {
            NSLog(@"%d", i);
            sleep(1);
        }
        if (identifier != UIBackgroundTaskInvalid) {
            [[UIApplication sharedApplication] endBackgroundTask:identifier];
            identifier = UIBackgroundTaskInvalid;
        }
    });
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    NSLog(@"%s", __PRETTY_FUNCTION__);
}

This example will start a background task when the app enters the background. The task is just a 20s delay (with logging once a second) that keeps the app running in the background (note the difference between running in the background and suspended) long enough to allow it to be killed from the app switcher.

So, to test it, run the app, hit the home button to send the app to the background, then before the 20s delay is up, remove the app from the app switcher. After the end of the 20s, -applicationWillTerminate: is called. You can watch the console in Xcode to verify that this is the case.

I tried this in the iOS Simulator for iOS 5.1 and 6.1 (both iPhone) and saw it happen in both cases. I also tested on iPhone 4S running iOS 6.1.2 and saw the same behavior.

like image 41
Andrew Hershberger Avatar answered Sep 17 '22 13:09

Andrew Hershberger


As I know, there are 3 situations that your application will die.

  1. Terminated by the end user, you can do something in -[UIApplication applicationWillEnterBackground:], in which case, -[UIApplication applicationWillTerminate:] will NOT be called.

  2. Dropped by the system, such as memory not enough, you can do something in -[UIApplication applicationWillTerminate:], in which case, we do NOT know whether applicationWillEnterBackground: has been called;

  3. Crashed, nothing can be done except using some kind of Crash Reporting Tool. (Edited: catching SIGKILL is impossible)

like image 28
DawnSong Avatar answered Sep 19 '22 13:09

DawnSong