Welcome to Day 25 of the 31 Days of iOS. Yesterday, we talked about the different parts of the view controller life cycle. This included events that are called automatically on a view controller when it is loaded, shows up to the user, is switched to another view, and more. Today we’re going to jump from the view to the application and talk about the application life cycle. While you don’t really need to see the code today to understand what is happening, there will be a project available for download. We’ll be starting with a brand new project, but if you’d like to follow along with the completed code, you can access it here.
Creating our project
Open up Xcode and choose File, New, Project. We’ll use a Single View Application and name it DayTwentyFive:
Since we’re really just going to be examining events on the application, we don’t need a UI for our project.
Application load life cycle events
Just from creating our application, we already have most of the app life cycle events present in our AppDelegate.m. Open that class and take a look. For the ease of seeing which methods are called in what order, I’ve added log statements to each method. When your app first runs, you’ll see that the first method fired is application: didFinishLaunchingWithOptions. This method is called one time when your application starts. Provided your application isn’t shut down by the user or the OS (and your app doesn’t die) this method won’t be called again. This is a great place for doing global initialization. Things like initializing singletons (for analytics) or registering for push notifications (which we’ll cover another day) are great candidates for this method. The next method that is called during launch is applicationDidBecomeActive. This method may be called more than once (as we’ll see) so you don’t necessarily want to do the same global initialization that you do in didFinishLaunchingWithOptions. Instead this is where you may want to start any background tasks you have (or unpause them if you previously paused them). You can also make calls to your UI to update it if necessary. This will become more important in just a moment. Let’s background our app by hitting the home key and then going back into our app to see what happens.
Backgrounding and returning to your app
When you hit the home key, the first method called is applicationWillResignActive. When this method is called you should begin to pause any tasks your application is running, disable timers, pause processing, end audio playback, etc. It’s important to note that this method is called whether the user hits the home key or if the app is interrupted by a phone call, for example. After this method, applicationDidEnterBackground will be called. In this method you should save any data important for restoring user state if the application is killed. Essentially, if the user then double taps home and kills your app, you won’t get a notification. When you return from this method, your application should have no problem being shut down or gracefully being reopened. It’s VERY important to note that you only get about 5 seconds of processing time when applicationDidEnterBackground is called. You can request additional time by using beginBackgroundTaskWithExpirationHandler. It’s critical to remember this because if you don’t return from the call to applicationDidEnterBackground fast enough, you’re app can be terminated. Now, double tap home and tap your app to relaunch it.
The first method called will be applicationWillEnterForeground. This method indicates that your app was previously in the background. If you stop anything when your app was backgrounded but didn’t fully kill it, you can restart it here. However, the applicationDidBecomeActive is called next. This means that you need to decide if you want to fully reinitialize things in DidBecomeActive or handle them in WillEnterForeground.
As I mentioned above, it’s important to know when applicationDidBecomeActive is called. This is because by default, your view controllers don’t receive an indicator when the app is backgrounded and then brought back into the foreground. You can, however, notify them from the applicationDidBecomeActive method. Additionally, you can look into using NSNotificationCenter to request an update be sent to your view controller when the DidBecomeActive method is fired.
There are a few other methods I’ll mention briefly. The applicationDidReceiveMemoryWarning is called on your app when it is using too much memory. This is an indicator from the OS that you should release memory if possible. As pointed out yesterday (for the same method on the view controller), with the use of Automatic Reference Counting, you don’t directly deallocate your memory. However you should still be cognizant of this method being called as it may mean you should redesign how your app works and uses memory. Also there is a method called applicationWillTerminate. This method is supposed to be called when your app is terminated, however, people seem to differ on how and when it will actually be called. In practice, other life cycle methods will be called before this and are the appropriate place to handle app shut down tasks. Additionally, there are two methods for push notifications: application: didReceiveRemoteNotification and application: didReceiveLocalNotification. These methods will be discussed in more detail when we talk about push notifications.
Today we reviewed the application life cycle. Combined with yesterday’s review of the view controller life cycle, you should now have a good understanding of what events are fired at what points in time. It’s very important to make sure your apps are good iOS citizens and correctly shut down or pause things when your app goes into the background and spin back up correctly when relaunched or brought into the foreground. Also remember, users are probably going to expect to be in the same place if they recently used your app. This means being able to remember what screen they were on, what data they had entered, and more. Make sure you think about this when building your apps. You can download the completed code from today’s walkthrough here.