I am trying to build an app and part of it deals with the need to distinguish between an application entering the background and an application quitting when the user presses closes it from the multi task pane. However from all my research online I find out that it is only possible to do one of the following:
a) Set 'application does not run in background' property in info.plist to YES and hence treat "going to background" as terminate
b) As a default the app going to background sends a notification but terminating it from the multi taskbar does not.
Is it possible to get a notification for both and ensure that the app does not terminate when going to background? Help is really appreciated. I am running the new ios 6.
Vivek
Use nsnotification to detect when the application terminates. This will let you know when the user terminates from the multitask bar
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationWillTerminate:)
name:UIApplicationWillTerminateNotification
object:app];
Which will call this selector in your file:
- (void)applicationWillTerminate:(NSNotification *)notification {
// Do stuff before termination
}
Otherwise it will just go into background mode depending on how your plist is configured
Whenever the user stops the application from the task manager pane, the application is sent a SIGKILL signal so it wont terminate gracefully and no selectors are called as a result.
If you want to ensure that the application does not get terminated(by the OS) the app should register as either needing GPS or Audio background modes (however bear in mind the application needs to really use the capabilities in the proper way, otherwise it will be rejected during the review process).
here is a simple explanation regarding the callbacks of the delegate:
applicationWillResignActive - whenvever the application is minimized OR a call is received
applicationDidEnterBackground - whenever the application is minimized by the user
applicationWillTerminate - whenever the OS decides to terminate the application to save memory (but not when killed by the user)
Related
How to know the termination of app?
I added this code in viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationWillTerminate:) name:UIApplicationWillTerminateNotification
object : nil];
and if the app ends, it will notify me of termination.
- (void)applicationWillTerminate:(NSNotification*) notif{
NSLog(#"program will end");
}
But it doesn't work...
I terminated the app, by clicking home button and pressing home button in 2sec, followed by clicking app icon's '-'button.
I want to be notified of the termination of app.
And also intereseted in what function to be called when the app terminates.(is it viewDidLoad?)
And the termination of app by clicking the '-'button is to send the app SIGKILL?
I terminated the app, by clicking home button and pressing home button in 2sec, followed by clicking app icon's '-'button.
If you press the home button, your app will be sent to the background. When you then kill it (by pressing the - button), it likely does not get the notification because it is not running anymore.
applicationWillTerminate is called on iOS < 4.0, when no multitasking (background) is available or when UIApplicationExitsOnSuspend is set in the info.plist file.
On iOS 4.x, when your app is sent to the background, it receives applicationWillEnterForeground:. Look at the UIApplicationDelegate Protocol Reference for more info:
You should 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.
Keep in mind that you need to do this both in applicationWillEnterForeground and applicationWillTerminate if you also support iOS < 4
Have a look also at this post from S.O.
That should work, did you try adding logging into the application delegate method applicationWillTerminate: method too?
Edit:
For iOS 4+ devices, you need to do whatever work for shutdown in applicationWillEnterBackground instead... that always gets called as you are being suspended and is the right time to do final work.
you should implement applicationDidEnterBackground and do any preparation for termination there. If your app is terminated in the background, you will receive no other notification.
I would like to schedule a local notification as soon as the user hits the home button.
Which App delegate method should I use in this case :
applicationWillResignActive
applicationDidEnterBackground
applicationWillTerminate
Well I guess I shouldn't use the third one, but what is the difference between the first two ?
Is there any way to distinguish getting interrupted by a phone call/other notification and actually pressing the home button ?
Thanks in advance.
To schedule local notification you shold use applicationDidEnterBackground instead of using applicationWillResignActive because applicationWillResignActive call every time when app get some specific interruption line phone call, sms. You want to schedule notification when user press home button and in this case applicationDidEnterBackground is the appropriate place to do this.
One thing that should be remember before using applicationDidEnterBackground is that this delegate has approximately five seconds to perform any task, if any task in this delegate will take more time then os will terminate your app. You can also request for additional time for execution by using beginBackgroundTaskWithExpirationHandler and then use a secondary thread to perform a task. For more detail about application delegates follow the links -
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIApplicationDelegate_Protocol/Reference/Reference.html
http://www.cocoanetics.com/2010/07/understanding-ios-4-backgrounding-and-delegate-messaging/
You should use applicationDidEnterBackground.
applicationWillResignActive gets called anytime your app is interrupted such as a phone call or SMS message. In this case if the user ignores these then your app will keep running in the foreground.
applicationDidEnterBackground only gets called when your app actually goes to the background.
You should do this in applicationDidEnterBackground:
applicationWillTerminate will not be
called when the user hits the home
button. With app switching this is
only sent when the user explicitly
quits the app or possibly in low
memory situations.
applicationWillResignActive is
additionally called when the app is
briefly interrupted, say by an SMS or
phone call alert. (Though if the user
then switches to Messages or Phone
app your app will eventually get a
applicationDidEnterBackground
message).
So it sounds like you're specifically interested in the point when the user taps the home button and the app goes to the background. applicationDidEnterBackground is the place.
You could also always schedule the local notification and only respond to it if the app isn't running when it occurs. Not better necessarily, just an option to consider.
I would like to know how i can detect when an application is about to be terminated. I mean really terminated, not just going into background mode. I have used this event, and it doesn't fire :
applicationWillTerminate
What i would really like to achieve is get some kind of event or notification when the user taps Home twice and presses the red baloon on the app. I don't care about the application going into background mode, there are a couple of events that handle this properly and they all work fine.
I need this so that i can "inform" my server to stop sending push notifications to APNS for apps that are terminated and aren't running in the background.
If you know of an easier way to achieve this, i'd be glad to hear :)
Thank you
Register your object (view controller, etc.) to listen for the UIApplicationWillTerminateNotification notification, and/or override the application delegate's -applicationWillTerminate: method and put your code there.
Angel, what you're asking for cannot be done. The app will be terminated with SIGKILL. Unstoppable, not catchable, no notifications. There is no difference between a system-initiated termination or one requested by the user.
You'll get applicationWillTerminate only if your app doesn't support background processing.
From UIApplicationDelegate docs on the matter:
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.
Seems to me that unless your background process is actively doing something in the background (not being suspended) it the applicationWillTerminate method will never get called.
I guess it depends what you definition of "being in the background" is.
IIRC it goes like this:
On start:
didFinishLaunchingWithOptions
applicationDidBecomeActive
Pressing home:
applicationWillResignActive
applicationDidEnterBackground
Coming back from home screen:
applicationWillEnterForeground
applicationDidBecomeActive
applicationWillTerminate is called when your application exits due to a call or the OS kills it for some reason.
I am wanting to save some app state data for when the user is quitting the app. I am thinking that I should be using the applicationWillTerminate method inside of my appDelegate, but when I try and do anything there, it's not doing anything:
- (void) applicationWillTerminate:(UIApplication *)application {
NSLog(#"test");
}
When I run my app, and do some stuff, and hit the home button to quit the app, nothing comes over the console...
Do I have to implement the applicationWillTerminate method in the appDelegate? The user of my app will most likely be in a Reader view when they leave, is there anyway to implement the app will close method there?
see this link iPhone simulator and applicationWillTerminate() for older iOS versions;
but remember the Home button does not necessarily terminate the application is ios4... you should use applicationDidEnterBackground but would suggest both places applicationWillTerminate and applicationDidEnterBackground
Adding the UIApplicationExitsOnSuspend key to your application’s Info.plist file and setting its value to YES will make you application quit when you hit the home button, even on iOS4
In iOS 4, the applicationWillTerminate: method is only called if you opt out of the background execution model. In the standard iOS 4 application lifecycle, applications are suspended (not terminated) when the home button is pressed. Your application delegate will receive an applicationWillResignActive: message followed by an applicationDidEnterBackground: message. The applicationDidEnterBackground: method is a good place to save user data.
Is there any possiblity for reacting to the event that a user kills your app via the multitasking bar if it has moved to the background? According to my observations, applicationWillTerminate: does NOT get called.
It seems to me that there is no possiblity for cleaning up before quitting in this case.
If an app needs to do any cleanup or shutdown, under iOS 4.x it should do this when the app's suspend delegate gets called, just before the app gets sent to the background, since there is no guarantee that the app will ever get any run time again, either due to user action or memory cleanup.
If the app's Deployment Target also includes iPhone OS 3.x, then it should also do cleanup in its terminate delegate, as that will get called instead of suspend.
It should get called. Are you depending on NSLog to tell you when it does get called? When an app goes into the inactive state by pressing the home button then any further NSLogs are not printed to the console. You could try showing a small UIAlertView to see of it does get called instead.