How exactly does applicationWillTerminate work on iPhone? - iphone

I'm considering how to make my iPhone application as "bullet proof" as possible.
Right now, I'm thinking about how the app will respond to the user hitting the home button at a critical point in the application's processing.
What exactly happens? Are any more instructions executed in the application's threads?
When applicationWillTerminate gets called, I've read that the application "has a few seconds before the os kills the process" - again, what exactly happens?

What I've observed is that the home screen appears immediately, but the app is allowed to continue running in the background for at least a few seconds. If it takes too long, it will get killed.

applicationWillTerminate is called when your application exits due to a call a user decides to take or when the OS kills it due to some other reason. You cannot stop the app from being terminated but can store some data which you want to use later in this method.
For instance if your app lets the user search for something, you can save the search term when the app is about to terminate (in applicationWillTerminate) method so you can use it later when the user logs in to the app again.
So the implementation of the method depends on what you want your app to do when the user decides to quit the app or the OS kills it.

I hear you get about 4.8 seconds to do processing from when applicationWillTerminate gets called otherwise it gets killed. Basically save anything you need quickly!

Related

Prevent app from shutting down when device is rebooted

When I restart the device my app is on it won't preserve the state it had once I open up the app again, it will be as if it's the first time I open, losing the session and having to re-login, how can I make my app preserve its state even through a device reboot? Like Twitter does, for example.
I'll try a bit more formal answer based on the comments you added above. I'll start by saying that the link Tim posted is something you should familiarize yourself with.
When your app is running, it's in the Foreground state. When you "exit" an app with the Home button, you're not really quitting it; you're just pushing it to the Background state. after a few seconds in background state, the OS automatically moves the app to the Suspended state. If you come back within a few minutes, your app is still in memory, so the OS just puts it back on the screen the way it was.
However, if you leave the app alone for a while and use other apps, the OS can--at any time and without warning--purge your app from memory. This is known as the "Not Running" state. Now, when the open the app again, it has to start from scratch. Obviously, the same thing happens when the device restarts--all apps are purged from memory.
The trick, then, is to save essential information about the app state whenever it enters the background state. You can use the app delegate's didEnterBackground method, or register for the UIApplicationDidEnterBackgroundNotification and invoke a method in your active view controller (or any other class, for that matter). Either way, you should save whatever state information you can.
How do you save this information? There are several strategies. For a simple app, perhaps you can register a few setting as NSUserDefaults. Or maybe you can write out a file containing whatever data the user was working on. It's really up to you.
Then, whenever the app launches, check for the presence of that saved data (however you chose to write it out), and set up the UI accordingly. To the user, it will appear as though the app never quit, which is exactly what Apple wants them to think.

Could iOS Kill an App in the Background?

While the device is powered on, is it possible for iOS to automatically terminate my app (calling applicationWillTerminate:) while it's in the background?
I'm also curious what happens in two other cases, three in total:
Device is powered on
Device is powered off
Device loses battery
I'm asking because I want to know how often applicationWillTerminate: is likely to get called. I want to know this because that's where I'm registering for remote notifications. And if there's a failure sending the device token to the server, I want to know how likely it is that that method will get called again (i.e., retry sending the device token to the server).
If your application supports multitasking (the default for anything linked against iOS 4.0+), this method will almost never be called. The documentation says it may be called in cases where the application is running in the background and the system wants to terminate. However, in my experience, I've only ever seen this actually called when running a music app that's actively playing music in the background and the system is jettisoning everything. In cases where I have background tasks running (not music, but short-term background tasks), I've seen the app terminated without this method being called.
I wouldn't ever rely on this being called and try and do all the clean-up you need to do in your delegate methods for transitioning into the background and your background task completion blocks (which do get executed for at least a few seconds before the app gets jettisoned).
Not only can iOS terminate your app automatically, but the user can kill it manually. In fact, the only time the user can kill your app is when it's in the background. Furthermore, when your app is "in the background" it's more likely to be suspended than actually running, so don't count on doing a lot of processing when you're not the foreground app.
As for how likely it is that you'll get -applicationWillTerminate:, that'll depend on the user and how they're using their device. You should handle it appropriately when you get it, and go about your business otherwise.
When memory is running low, iOS can shut down your app, calling applicationWillTerminate.
The docs say this about the method:
... 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.
Check out iOS Developer Library : iOS App Programming Guide : App Termination.

Killing iOS app upon user request

So here is the issue I am facing. Certain portions of the application I am building open some c network sockets that allow connections to various servers/services. However, if the application goes to sleep, these socket connections are lost, and error out when trying to reload them. So what I want to do is basically notify the user when the app launches again, that the application needs to be restarted. The main question is, can I present them with a button that will kill the app by using exit(0) without my app getting rejected?
Apple says that the user should be in control of when the app is killed, and in this case I see that they are, but I am not sure of Apple's opinion on this. Has anyone else used this? Have you been rejected for this? Thanks in advance for any advice!
EDIT:
Thank you everyone for your advice. I am trying to take everything into consideration, but because the app needs to be submitted ASAP, I just need to know, if we can not get another solution, if the above proposed solution, will get rejected or not.
Your application delegate receives notifications when significant events affect the life of the application. Rather than ask your user to recreate a session, you should attempt to discontinue network operations and then resume them at the appropriate times in the application's lifecycle automatically.
You can gracefully kill network sockets (amongst other things) in any number of places as the application prepares to exit or enter the background via callbacks in your application delegate:
applicationWillResignActive:
applicationWillEnterBackground:
applicationWillTerminate:
Potentially reconstruct sockets in:
applicationDidBecomeActive
applicationWillEnterForeground
Have you tried not allowing the app to run in the background? Then it will be killed whenever the user exits to the home screen. This might be a bit aggressive, but would solve the problem. From Apple's opting out of background execution:
"If you do not want your application to remain in the background when
it is quit, you can explicitly opt out of the background execution
model by adding the UIApplicationExitsOnSuspend key to your
application’s Info.plist file and setting its value to YES.
When an application opts out, it cycles between the not running,
inactive, and active states and never enters the background or
suspended states.
When the user taps the Home button to quit the application, the
applicationWillTerminate: method of the application delegate is called
and the application has approximately five seconds to clean up and
exit before it is terminated and moved back to the not running state."
See also: How to prevent my app from running in the background on the iPhone
The documentation is pretty explicit about this, "There is no API provided for gracefully terminating an iOS application." See Technical Q&A QA1561
How do I programmatically quit my iOS application?.
To be blunt, terminating an app to cleanup a socket is just like dealing with memory management by forcing an app to exit instead of calling release.
What about bringing up a modal view controller telling the user to quit the application? You could make this view controller without any dismiss button, so the user is obligated to kill the app.

iPhone force kill while in background using CLLocationManager

Does anyone know how to detect if the user has force killed my app while the app is in the background? In the Apple documentation for the applicationWillTerminate: method it says this:
"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."
From my testing, when I force kill the app, my app still looks like it is tracking my location (the arrow is still at the top). But the cllocationmanager delegate method is not getting called until the app is relaunched, and the manager is stopped then started again. What is the best way, if any, to handle this situation?
Thanks!
UPDATE:
After looking into this post: Behaviour for significant change location API when terminated/suspended?
I'm still left with a problem. Because I'm using the method startUpdatingLocation, rather than the startMonitoringSignificantLocationChanges method. It looks like the application is only relaunched if you are logging significant changes. It seems to me that's it's kinda a hack to log significant changes just so I don't lose the app. Any ideas?

APPLICATION WILL TERMINATE IS NOT WORKING IN Below Case

I m facing big problem With Application Termination State.In My app
need to Satisfied Following Points.....
1)Application Is in Back Ground Switch To Fore Ground (no Need To
Store Data)
2)Application Is Background After Some Time If User Go to home And
Terminate Application (need To Store Data)
is there any delegate method Will Call Before Application
Terminate . - (void)applicationWillTerminate:(UIApplication
*)application
Is not Working With Because In 1 Case Application Running So
Suspended When We Try to Terminate Application.
Please Help me Out From This Issue..... If Any Ideas Also Would Be
Appropriated
You should always store your data when going into the background (applicationDidEnterBackground:). There is no guarantee that you will receive any further opportunities prior to being terminated.
This is how it's supposed to work. This is what it says in the documentation:
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
If there is data that you need to save, you should do it when the app goes into the background.
No there is nothing called, because your app killed by the OS, this could also happen if the system need more free memory.
You should save the data when every your app gets send to the background, not when it gets terminated.