UIApplicationDidEnterBackgroundNotification - iphone

whats the use of UIApplicationDidEnterBackgroundNotification in iPhone app or how we can take benifit from it

This notification means the user "quit" your app on an iPhone 4 - It happens when a phone call or text message comes in and user accepts the interruption (answers/replies), or when the user has pressed the Home button.
I found this link on SO that shows the interaction between all states, and the appropriate notifications:
http://www.drobnik.com/touch/2010/07/understanding-ios-4-backgrounding-and-delegate-messaging/
To make use of this notification you can implement applicationDidEnterBackground as #Antwan suggested (in your UIApplicationDelegate class - that's the main class).
Alternatively you could set up a notification handler wherever you want/need in your code:
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(handleEnteredBackground:)
name: UIApplicationDidEnterBackgroundNotification
object: nil];
Good luck!
Oded.

From apple documentation.
Tells the delegate that the application is now in the background.
- (void)applicationDidEnterBackground:(UIApplication *)application
Parameters
application
The singleton application instance.
Discussion
In iOS 4.0 and later, this method is called instead of the applicationWillTerminate: method when the user quits an application that supports background execution. 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. You should also disable updates to your application’s user interface and avoid using some types of shared system resources (such as the user’s contacts database). It is also imperative that you avoid using OpenGL ES in the background.
Your implementation of this method has approximately five seconds to perform any tasks and return. If you need additional time to perform any final tasks, you can request additional execution time from the system by calling beginBackgroundTaskWithExpirationHandler:. In practice, you should return from applicationDidEnterBackground: as quickly as possible. If the method does not return before time runs out your application is terminated and purged from memory.
You should perform any tasks relating to adjusting your user interface before this method exits but other tasks (such as saving state) should be moved to a concurrent dispatch queue or secondary thread as needed. Because it's likely any background tasks you start in applicationDidEnterBackground: will not run until after that method exits, you should request additional background execution time before starting those tasks. In other words, first call beginBackgroundTaskWithExpirationHandler: and then run the task on a dispatch queue or secondary thread.
The application also posts a UIApplicationDidEnterBackgroundNotification notification around the same time it calls this method to give interested objects a chance to respond to the transition.

Related

Managing Memory in App When Running in Background - correct Procedure?

I've just been reading this post on notifications being sent to apps running in the background :
Not getting didReceiveMemoryWarning when app is in the background
My question is that since an app in the background will not act on a didRecieveMemoryWarning until it enters the foreground again, what is the recommended way to free up memory in your app if it is running in the background when the memory notification is sent - or is this not possible ?
In iOS 4.0 and later, - (void)applicationDidEnterBackground:(UIApplication *)application method is called instead of the applicationWillTerminate: method when the user quits an application that supports background execution.
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.
You should also disable updates to your application’s user interface and avoid using some types of shared system resources (such as the user’s contacts database). It is also imperative that you avoid using OpenGL ES in the background.
Your implementation of this method has approximately five seconds to perform any tasks and return. If you need additional time to perform any final tasks, you can request additional execution time from the system by calling beginBackgroundTaskWithExpirationHandler:. In practice, you should return from applicationDidEnterBackground: as quickly as possible. If the method does not return before time runs out your application is terminated and purged from memory.
If your app is running in the background (because it is, for example, a Voice over IP app that is allowed to run in the background), it will receive memory warning notifications in the same way as if it were running in the foreground, and you should deal with them accordingly.
However, if your app is suspended in the background, it won't receive memory warnings or other notifications. Your job is to free as much memory as possible before your app enters the background. Once you're in the background, you have no way to do anything anymore. The OS will decide whether to kill your app or not (without notifying you again) at its discretion.

How to save state of app on application exit

I am working on an iphone game app. I dont want to use core data or nsuserdefaults to store user data. instead i want to keep all activities in memory and then send it to server when user goes back to previous screen, ends game or presses the home button of iphone. Now everything works fine but i am not able to sync user data when user presses home button. I have implemented the appilcationWillTerminate method in my delegate class but its not working out for me as the method is not get called when I press home button of iphone. Can anyone please tell me how to achieve this task?
best regards
What about this method:
Tells the delegate that the application is now in the background.
- (void)applicationDidEnterBackground:(UIApplication *)application
From Apple Docs:
In iOS 4.0 and later, this method is called instead of the applicationWillTerminate: method when the user quits an application that supports background execution. 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. You should also disable updates to your application’s user interface and avoid using some types of shared system resources (such as the user’s contacts database). It is also imperative that you avoid using OpenGL ES in the background.
Your implementation of this method has approximately five seconds to perform any tasks and return. If you need additional time to perform any final tasks, you can request additional execution time from the system by calling beginBackgroundTaskWithExpirationHandler:. In practice, you should return from applicationDidEnterBackground: as quickly as possible. If the method does not return before time runs out your application is terminated and purged from memory.
You should use NSUserDefaults to store data about the application state. Then, when the application re-starts, you can load the data from NSUserDefaults to recreate the previous state. However with the new multitasking this is not as necessary as it used to be a couple of years ago.

dumping data to file when app quits

What do you all recommend as the best location in an iphone project to dump data collected from the user to a local file? Would you say that applicationWillTerminate is a good option?
Thanks!
A better option on iOS 4.x is applicationDidEnterBackground:
Indeed, according to Apple docs, an application in the background can be terminated at any time due to low memory conditions. Therefore, the suggestion is making persistent any state information at the moment the app enters background.
An excerpt from the UIApplicationDelegate protocol:
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. You should also disable updates to your application’s user interface and avoid using some types of shared system resources (such as the user’s contacts database). It is also imperative that you avoid using OpenGL ES in the background.
Your implementation of this method has approximately five seconds to perform any tasks and return. If you need additional time...
Also from Apple Docs for applicationWillTerminate:
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.
Therefore if you specifically request to not support backgrounding for your app or you link against iOS 3.x you should consider persisting in both places (applicationWillTerminate and applicationWillEnterBackground) to catch situations as well.

When an iOS application goes to the background, are lengthy tasks paused?

Yes, I know if I wish my app to be responsive to users' multitasking actions, such as switch to another app, I should deal with
- (void)applicationWillResignActive:(UIApplication *)application
- (void)applicationDidBecomeActive:(UIApplication *)application
What if my app is doing a quite-long time consuming operation (like downloading a big file) and the user causes my app to enter the background? Will that operation automatically be suspended and resumed when the user comes back to my app?
What exactly will happen behind the scene when my app enters the background or resumes in the foreground?
What if when users let my app go to the background my app's execution is just in the middle of a method?
For e.g., my app is doing
for (int i = 1 to 10000K) {
do some calculation;
}
When i== 500K, user switches to another app. What happens to the for-loop in my app?
From the documentation:
Return from applicationDidEnterBackground(_:) as quickly as possible. Your implementation of this method has approximately five seconds to perform any tasks and return. If the method doesn’t return before time runs out, your app is terminated and purged from memory.
If you need additional time to perform any final tasks, request additional execution time from the system by calling beginBackgroundTask(expirationHandler:). Call beginBackgroundTask(expirationHandler:) as early as possible. Because the system needs time to process your request, there’s a chance that the system might suspend your app before that task assertion is granted. For example, don’t call beginBackgroundTask(expirationHandler:) at the very end of your applicationDidEnterBackground(_:) method and expect your app to continue running.
If the long-running operation you describe above is on the main thread and it takes longer than 5 seconds to finish after your application heads to the background, your application will be killed. The main thread will be blocked and you won't have a chance to return from -applicationDidEnterBackground: in time.
If your task is running on a background thread (and it really should be, if it's taking long to execute), that thread appears to be paused if the application returns from -applicationDidEnterBackground: (according to the discussion in this answer). It will be resumed when the application is brought back to the foreground.
However, in the latter case you should still be prepared for your application to be terminated at any time while it's in the background by cleaning things up on your way to the background.
If you are doing some operation which might consume time and you don't want to kill it then you can extend the time for your operation by executing in UIBackground Task i
{
UIBackgroundTaskIdentifier taskId = 0;
taskId = [application beginBackgroundTaskWithExpirationHandler:^{
taskId = UIBackgroundTaskInvalid;
}];
// Execute long process. This process will have 10 mins even if your app goes in background mode.
}
The block argument called "handler" is what will happen when the background task expire (10min).
Here is a link to the documentation
Like mentioned above, there are a few cases where your app runs in the background and apple can allow or deny depending on what you are doing.
https://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html
More importantly if you do fit into one of these categories your app refresh rate is determined by an apple algorithm that takes into consideration your app usage on that device vs other apps. If your app is used more often then it gets more background time allotted. This is just one variable but you get the idea that background time allocation varies app to app and not under your control.

How can I determine when my application is about to be terminated in the background?

When my application is moved into the background, I'd like to be able to detect when it is about to be terminated (for memory exhaustion or other reasons). Is there a way to do this?
In particular, is there a way to execute some code before the application is terminated when in the background?
You can do this in the -[<UIApplicationDelegate> applicationWillTerminate:] method of your application delegate, like this:
- (void)applicationWillTerminate:(UIApplication *)application {
[database save]; // or whatever you want to do
}
This will be executed whenever the app is about to be terminated, unless it crashes.
Your best bet is to do whatever cleanup needs to be done in your application (saving state or user data, etc.) as your application transitions into the background. If your application is suspended, you will not have a chance to perform any last code before it is terminated by the system.
From the iOS Application Programming Guide:
If your application is running (either
in the foreground or background) at
termination time, the system calls
your application delegate’s
applicationWillTerminate: method so
that you can perform any required
cleanup. You can use this method to
save user data or application state
information that you would use to
restore your application to its
current state on a subsequent launch.
Your method implementation has
approximately 5 seconds to perform any
tasks and return. If it does not
return in time, the application is
killed and removed from memory. The
applicationWillTerminate: method is
not called if your application is
currently suspended.
Even if you develop your application
using iOS SDK 4 and later, you must
still be prepared for your application
to be killed without any notification.
The user can kill applications
explicitly using the multitasking UI.
In addition, if memory becomes
constrained, the system might remove
applications from memory to make more
room. If your application is currently
suspended, the system kills your
application and removes it from memory
without any notice. However, if your
application is currently running in
the background state (in other words,
not suspended), the system calls the
applicationWillTerminate: method of
your application delegate. Your
application cannot request additional
background execution time from this
method.
It depends.
If you mean getting notification while your application is suspended in the background, there is no way to know; the applicationWillTerminate: method is not run if you're suspended. The recommended approach is to save any required state when you get the applicationWillEnterBackground: message, so that if you get killed in the background you're ready to start up again.
If you're actually in an "executing in the background" state, (which can happen briefly after exiting the app or if the app has requested temporary background execution time,) then applicationWillTerminate: will be called just like you'd expect.