applicationWillTerminate: not being called - ios

I'm using applicationWillTerminate: to save some last-minute stuff. But the problem is that it never gets called. If I do something like this at the top of the method: NSLog(#"Something"); it doesn't get called and doesn't get outputted to the console.
Does anyone know why this is happening?

From Apple docs:
For applications that do not support background execution or are linked against iOS 3.x or earlier, this method is always called when the user quits the application. 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.
If your app has background enabled use:
- (void)applicationDidEnterBackground:(UIApplication *)application

Use applicationDidEnterBackground: instead. Applications aren't terminated when you press the home button in a multitasking system.

From the iOS Application Programming Guide on Core Application Design and Application life time:
The applicationWillTerminate: method is not called if your application is currently suspended.
If you are linking against iOS 4.0, you should also save data in applicationDidEnterBackground:.

step 1: command + shift + h (double click(tab))
step 2: move app top side (kill)
step 3: applicationWillTerminate Work

Related

iOS - How to guarantee that applicationWillTerminate will be executed

Is there A way to guarantee that the applicationWillTerminate method in the AppDelegate delegate will be hit? Something like a key in the info.plist file, etc..?
My goal: I'm working in a beacon app, the piece of code is in this article. My problem is that the message from the didEnterRegion keeps poping even when i'm beside the beacon. To solve that I'm setting a flag to control the message. My code below:
if(!UserDefaults.standard.bool(forKey: Constants.EnterZoneMsgShowName)){
let notification = UILocalNotification()
notification.alertBody = "Hi, you are about to arrive at CIDMA's office. Please open de demo app and turn on the bluetooth on your device to enrich your experience. "
UIApplication.shared.presentLocalNotificationNow(notification)
UserDefaults.standard.set(true, forKey: Constants.EnterZoneMsgShowName)
}
I want to set this flag to false when I close the app. I tried to put it at the applicationWillTerminate but this method is not hit every time.
I would like to know how to guarantee that this code will be hit or if there is a better place to put the code: UserDefaults.standard.set(false, forKey: Constants.EnterZoneMsgShowName)
applicationWillTerminate(_:) - Tells the delegate when the app is about
to terminate.
For apps that do not support background execution or are linked against iOS 3.x or earlier, this method is always called when the user quits the app.
For apps that support background execution, this method is generally not called when the user quits the app because the app simply moves to the background in that case. However, this method may be called in situations where the app is running in the background (not suspended) and the system needs to terminate it for some reason.
What you want to call is applicationDidEnterBackground if your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.

SWIFT: how to run a function even when user kills the app

I am using swift 2 and Xcode7 for iOS9. I want to know if I can maintain a function (that checks for something to delete) running "forever" even if the user kills the app?
I am deleting contacts from the contact list according to some rules and time. It is running ok, but just with the app opened or in second plan. I want to make this app capable to delete those contacts even when the user kills it.
You can use background thread when user opens the app. But if the app will be terminated, there is no option to run functions.
Look for the app lifecycle here and redesign your architecture: https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html
If the user kills the app it is no longer running, therefore your code is no longer running. There is no such state that your code/app can be in where this is possible.
By "kill", I don't mean "background". Backgrounding an app is different. Check Apple's docs on the different app states (see m.albin's answer) as well as various strategies for handling those app states.
func applicationWillTerminate(_ application: UIApplication) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
print("Application Will Terminate")
}

Programmatically Terminate an iOS App Extension [duplicate]

At some point in my application I have done this exit(0) which crashes my app. But I haven't figured out what method gets called when this executes.
I've put messages in:
(void)applicationWillTerminate:(UIApplication *)application
(void)applicationDidEnterBackground:(UIApplication *)application
But none of this seem to get called! Any idea about what method is called when exit(0) is done?
From Apple's Human User Guidelines...
Don’t Quit Programmatically
Never quit an iOS application programmatically because people tend to
interpret this as a crash. However, if external circumstances prevent
your application from functioning as intended, you need to tell your
users about the situation and explain what they can do about it.
Depending on how severe the application malfunction is, you have two
choices.
Display an attractive screen that describes the problem and suggests a
correction. A screen provides feedback that reassures users that
there’s nothing wrong with your application. It puts users in control,
letting them decide whether they want to take corrective action and
continue using your application or press the Home button and open a
different application
If only some of your application's features are not working, display
either a screen or an alert when people activate the feature. Display
the alert only when people try to access the feature that isn’t
functioning.
If you've decided that you are going to quit programmatically anyway...
In C, exit(0) will halt execution of the application. This means that no delegate methods or exception handlers will be called. So, if the goal is to make sure that some code gets called when the closes, even on a forced close, there may be another option. In your AppDelegate implement a custom method called something like -(void)applicaitonIsgoingAway. Call this method from within anywhere you want your exiting code to be called:
applicationWillTerminate
applicationDidEnterBackground
onUncaughtException
The first two are ones that you already mentioned in your question. The third can be a catch-all of sorts. It's a global exception handler. This next bit comes from a question on that very topic.
This exception handler will get called for any unhanded exceptions (which would otherwise crash your app). From within this handler, you can call applicaitonIsgoingAway, just like in the other 2 cases. From the other question that I mentioned above, you can find an answer similar to this.
void onUncaughtException(NSException* exception)
{
[[AppDelegate sharedInstance] applicationIsgoingAway];
}
But in order for this to work, you need to set this method up as the exception handler like so...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSSetUncaughtExceptionHandler(&onUncaughtException);
//There may already be more code in this method.
}
Now, you can quit the app programmatically by calling NSAssert(FALSE, #"Quitting the app programmatically."); As long as there is no other exception handler in place to catch this, your app will begin to crash, and your exception handler code will be called. in-turn calling applicationIsGoingAway.
When you call exit(0) you immediately terminate your application. 0 is a status code which means successful termination.
No other method is called, you application just dies. As a result end user may think app is just crashed.
Apple discourages you to call exit anywhere.
exit(0) is a C function that terminates your app's process therefore none of the application delegates methods will be called, the app will be killed immediately. Apple recommends strongly against your app quitting because it appears broken to the user.
There is no Apple-supported method to terminate your application programmatically. Calling exit is certainly out of the question. This causes all sorts of bugs (for example the multitasking switcher will break badly) as well as simply being wrong.
If you are trying to disable multitasking, you can do this with the UIApplicationExitsOnSuspend key in your Info.plist file (the title for the key is "Application does not run in background").
Other than that, it's up to your users to press the home button to close your application.
these methods will be called but you cannot use exit(0) you will need to press the back button to close your app then these methods will be called

Where do I put logic for when an iOS application hard closes and comes back?

I have an iOS application where I need to persist a set of data after the application HARD CLOSES (when the user double clicks the Home button and slides the application upwards). Then, when the application comes back to the foreground, I need to fetch that data and do something with it. I'm just not sure where I need to put that logic for Application Hard Close and Resuming the Application.
In your AppDelegate
When your app is going to be closed, but still in Multitasking menu the following method is getting called
-(void)applicationWillResignActive:(UIApplication*)application
If after 3 minutes user doesn re-open your app this method is going to be called
-(void)applicationDidEnterBackground:(UIApplication*)application
If user re-opens your app from multitasking menu the following method is getting called
-(void)applicationWillEnterForeground:(UIApplication*)application
If user is going to close your app from multitasking menu this method is getting called(you will have limited time to perform some logic here)
-(void)applicationWillTerminate:(UIApplication*)application
When user presses home twice applicationWillResignActive and applicationDidEnterBackground is called. You can save data here.
When user opens app, applicationWillEnterForeground is called, you get data which you save and process.
When a user hard-closes the application, the UIViewController's Delegate's method called applicationWillTerminate. Here I can catch and save the model data before it's all destroyed.
Then when a user launches the application again, there are many choices like didFinishLaunchingWithOptions where I can grab the data stored to disk.
Your app no longer gets an applicationWillTerminate call ever. You are simply silently killed while in the background. You have to write your app to save state in the applicationDidEnterBackground handler, as nmh describes. That's your only option.

call exit(0) in iphone app

At some point in my application I have done this exit(0) which crashes my app. But I haven't figured out what method gets called when this executes.
I've put messages in:
(void)applicationWillTerminate:(UIApplication *)application
(void)applicationDidEnterBackground:(UIApplication *)application
But none of this seem to get called! Any idea about what method is called when exit(0) is done?
From Apple's Human User Guidelines...
Don’t Quit Programmatically
Never quit an iOS application programmatically because people tend to
interpret this as a crash. However, if external circumstances prevent
your application from functioning as intended, you need to tell your
users about the situation and explain what they can do about it.
Depending on how severe the application malfunction is, you have two
choices.
Display an attractive screen that describes the problem and suggests a
correction. A screen provides feedback that reassures users that
there’s nothing wrong with your application. It puts users in control,
letting them decide whether they want to take corrective action and
continue using your application or press the Home button and open a
different application
If only some of your application's features are not working, display
either a screen or an alert when people activate the feature. Display
the alert only when people try to access the feature that isn’t
functioning.
If you've decided that you are going to quit programmatically anyway...
In C, exit(0) will halt execution of the application. This means that no delegate methods or exception handlers will be called. So, if the goal is to make sure that some code gets called when the closes, even on a forced close, there may be another option. In your AppDelegate implement a custom method called something like -(void)applicaitonIsgoingAway. Call this method from within anywhere you want your exiting code to be called:
applicationWillTerminate
applicationDidEnterBackground
onUncaughtException
The first two are ones that you already mentioned in your question. The third can be a catch-all of sorts. It's a global exception handler. This next bit comes from a question on that very topic.
This exception handler will get called for any unhanded exceptions (which would otherwise crash your app). From within this handler, you can call applicaitonIsgoingAway, just like in the other 2 cases. From the other question that I mentioned above, you can find an answer similar to this.
void onUncaughtException(NSException* exception)
{
[[AppDelegate sharedInstance] applicationIsgoingAway];
}
But in order for this to work, you need to set this method up as the exception handler like so...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSSetUncaughtExceptionHandler(&onUncaughtException);
//There may already be more code in this method.
}
Now, you can quit the app programmatically by calling NSAssert(FALSE, #"Quitting the app programmatically."); As long as there is no other exception handler in place to catch this, your app will begin to crash, and your exception handler code will be called. in-turn calling applicationIsGoingAway.
When you call exit(0) you immediately terminate your application. 0 is a status code which means successful termination.
No other method is called, you application just dies. As a result end user may think app is just crashed.
Apple discourages you to call exit anywhere.
exit(0) is a C function that terminates your app's process therefore none of the application delegates methods will be called, the app will be killed immediately. Apple recommends strongly against your app quitting because it appears broken to the user.
There is no Apple-supported method to terminate your application programmatically. Calling exit is certainly out of the question. This causes all sorts of bugs (for example the multitasking switcher will break badly) as well as simply being wrong.
If you are trying to disable multitasking, you can do this with the UIApplicationExitsOnSuspend key in your Info.plist file (the title for the key is "Application does not run in background").
Other than that, it's up to your users to press the home button to close your application.
these methods will be called but you cannot use exit(0) you will need to press the back button to close your app then these methods will be called

Resources