iOS4: application termination event? - iphone

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.

Related

applicationDidEnterBackground & applicationWillResignActive are not being called

I am creating a simple application which perform some task on main thread. I am printing process in NSLog so I can understand that my process is running or not.
Now when I press home button without starting the process (Process will be start when I tap on a button) application enters in background and my both of methods applicationDidEnterBackground & applicationWillResignActive are being called.
But when I first tap on my button and process starts on main thread after that if I press home button none of these two method being called. So my application can't know that app entered in background or not.
Even after that when I again active the app it shows me a black screen with status bar only.
Why this is happening?
Why app not entering in background?
Why apple's methods not being called?
Is there a way to solve it?
UPDATE
Here is my appdelegate class code
- (void)applicationWillResignActive:(UIApplication *)application
{
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
}
All methods have no implementation.
Thanks in advance.
I am creating a simple application which perform some task on main thread.
Don't perform long-running operations on the main thread.
The delegate callbacks happen on the main thread. If the main thread is busy, then the callbacks won't happen until you return to the "run loop".
When foregrounding your app, the OS actually displays a screenshot if available, falling back to the launch image (Default.png). The screenshot is taken after -applicationDidEnterBackground: returns, which allows you to customize what gets saved (you might want to do this for security reasons, or to hide UI elements which might not make sense to show when relaunching e.g. a countdown timer).
The black screen is probably because your app has no launch image. If your app takes more than about 10 seconds to enter the background (and it does, since the main thread is blocked), it gets killed. Except the debugger is attached and catches SIGKILL, so it's easy to miss unless you're watching Xcode.
there are some cases
if UIApplicationExitsOnSuspend key set to true in your app's Info.plist, the applicationWillResignActive method is not called when the user hits the home button. and may b some thing other. check keys here Apple keys and see if something new you added to plist. and there is no other case that you say your delegate method not calling. it may also some time due to project in appropriate behavior. try cleaning your project and rebuild.
this is going to sound strange but for those it helps. I had the same issue and cleaned my project and then it started working again.

Home button press , Which AppDelegate method should i use for scheduling a local 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.

Multitasking and termination

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.

Detect Application States

I want to detect application states and send it to the server. In the new OS4, with multitasking there are some methods available to help detecting the states:
application:didFinishLaunchingWithOptions:
applicationDidBecomeActive:
applicationWillResignActive:
applicationDidEnterBackground:
applicationWillEnterForeground:
applicationWillTerminate:
I read that now, we have to use applicationDidEnterBackground instead of applicationWillTerminate. My problem is that i need them both.
When the user send the app to the background, it has the state sleep. But when the user close the app ( from the multitask bar ) the state is closed. So i need to detect both, when the user send the app to the background and when the user ( or the system ) close it.
Is there anyway or workaround to make this?
I try subscribing to UIApplicationWillTerminateNotification but it doesn´t work.
Thanks in advice.
The application will quit notification is no longer fired on iOS 4 (as I am led to believe).
When the user hits the home button, the app is sent to the background, and you will get the did enter background notification. But when a user closes the app from the multitask bar, or if the system closes it, the app is sent a SIGKIL message and quits immediately, firing no notifications or delegate methods.

Will an iPhone app's applicationWillResignActive: method run on incoming call if the phone is already in standby mode?

I understand that if an iPhone app is interrupted (e.g., incoming call, user hits the "Sleep" button, etc.) its applicationWillResignActive: method is called. But is this method also called if the phone is already in sleep mode?
For example, if the phone goes into standby due to inactivity (or the user does it manually via the sleep button), the applicationWillResignActive: method is called once. Will it then be called a second time if an incoming call is received while in the sleep state?
No. I finally had some time to come back to this question and do some testing to answer it.
applicationWillResignActive is called when the screen locks (either manually by pushing the button on top of the device or automatically if you have the auto-lock feature enabled). If an incoming call is received while the screen is locked (i.e., blacked out), none of the applicationWillX or applicationDidX methods are called on the app delegate.