I am developing a game for the iPhone. I do not actually have an iPhone, so I am testing my game on an iPod device (version 4.2.1). When I press the home button the game starts from level one. I find this odd, since in the simulator, after pressing the home button, the game starts from the same state where I stopped. I am unsure as to why the behavior is different on the iPod, maybe I need to handle the AppDelegate method differently (is it not handled automatically depending upon the device?)
How can I handle this issue?
It appears that the device you are testing your app on does not support multi tasking.
The older iPod touches and iPhones do not support multi tasking an close the app rather than suspending them.
All device that can run iOS 4.3 or higher will support backgrounding. Devices that can't update above 4.2.1 will not support backgrounding and app will be closed if you press the home button.
You will need to save the game state in the apps delegate applicationWillTerminate:
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
Save the current game state here and read them in - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
When the application is on and when we leave it to idle, the screen gets lock. When the user unlocks it (slides), I need to relaunch the application.
For that i used the following code in the applicationDidFinishLaunching method.
[[UIApplication sharedApplication] setIdleTimerDisabled: YES];
Still the application doesn't relaunch after the screen is unlocked. Help, what should i do to make this work ?
You do not have to do anything for that. If an application is open before locking the iphone, it will be open, if you unlock it again.
setIdleTimerDisabled just ensures, that the device won't go to sleep on its own, while your application is running. In most cases you shouldn't use this application-wide.
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.
For IOS (without multitasking) it is called always when home button is pressed.
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?
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.
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.
As I know, there are 3 situations that your application will die.
Terminated by the end user, you can do something in -[UIApplication applicationWillEnterBackground:], in which case, -[UIApplication applicationWillTerminate:] will NOT be called.
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;
Crashed, nothing can be done except using some kind of Crash Reporting Tool. (Edited: catching SIGKILL is impossible)
Source: http://www.cocos2d-iphone.org/forum/topic/7386
I copied my state saving code from applicationWillTerminate to applicationDidEnterBackground and also added a multitaskingEnabled boolean so that I only call state saving in applicationDidEnterBackground. BECAUSE, there is one instance on a multitasking device where applicationWillTerminate is called: If the app is in the foreground and you power off the device. In that case, both applicationDidEnterBackground and applicationWillTerminate get called.
As we know that the App has only 5 sec when -applicationWillTerminate being called. So If someone want to update the server at that point. Than use
Synchronous call.
[NSURLConnection sendSynchronousRequest:urlRequest returningResponse:nil error:&error];
Note:- -applicationWillTerminate will not call if app is being killed from suspended state. Suspended state means app is not working anything in backgroupd. One of the solution for this is to use background task.
Based on Andrew's test, I understand the docs for applicationWillTerminate(_:) to be meant as having the following clarifications:
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 [right away] when the user quits the app because the app simply moves to the background in that case. However, this method may be called [instead of beginBackgroundTask(expirationHandler:)] in situations where the app is running in the background (not suspended) and the system needs to terminate it for some reason.
// absolute answer applicationWillTerminate
func applicationWillTerminate(application: UIApplication) {
print("applicatoinWillTerminate")
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
step 1: command + shift + h (double click(tab))
step 2: move app top side (kill)
step 3: applicationWillTerminate Work
I have an iPhone application which I'm working on and so far i have created a login page for the application such that only the phone's user can access the application. The login works fine and the application works fine, but when i hit the home button, the app is "minimized". And if accessed again from the task switcher it doesn't prompt for a password.
What exactly would be the best way to go about getting the app to request a password. If it helps i use navigation controllers and i have one view dedicated for the login.
Thanks for the help.
Can't you check app activated in the appdelegate?
- (void)applicationDidBecomeActive:(UIApplication *)application {
[self showLoginWindow];
}
You must be working on iOS4. When you hit on Home Button, your app goes into background mode, but still working. So next time, when you open it, it starts exactly from where you left it. Implement the
- (void)applicationDidBecomeActive:(UIApplication *)application
method, to check for login again. Or if you don't want the background processing at all, disable it or use following code
- (void)applicationDidEnterBackground:(UIApplication *)application {
exit(0);
}
EDIT -
Don't go for exit(0) approach, simply disable the background processing if you don't want it from info.plist file.
see this link
you need to prevent the app to load from background.
I want to cancelAllLocalNotifications and setApplicationIconBadgeNumber to 0 when my application is terminated (either by the OS or by double tapping the home button and killing the app). I simply added these two calls to my primary app delegate code:
-(void)applicationWillTerminate:(UIApplication *)application
{
[application cancelAllLocalNotifications];
[application setApplicationIconBadgeNumber:0];
}
Existing notifications are still running and the badge number remains set?
applicationWillTerminate: is not called by the OS when it kills your app. The OS just kills the process without notifying your app about it. There is no documented way to execute code at this moment.
You should use applicationWillResignActive: instead.
Starting with iOS 4.0 applicationWillTerminate is not called for applications when they are killed in the background. Apps are put in the background when you hit the home button now or otherwise switch apps.