Measuring App Sessions on iOS 4

Before Apple iOS 4, tracking mobile app sessions on iPhone was very straightforward. Only one app could run at a time and every app had a clearly defined starting and ending point. With the introduction of multitasking in iOS 4, apps are no longer terminated when a user exits but are instead moved to the background and resumed when the user returns. In fact, many apps such as music players and messaging clients are intended to persist in the background indefinitely without any defined stopping point. As a result, the old way of tracking app sessions no longer accurately reflects the users’ behavior.

Consider an iPhone user running an app and then receiving a text message. The user was engaged in the first app and will now switch to the messaging app to review the message. If the user just reads the message and switches back to the app in a few seconds it is reasonable to consider that a continuation of the original session. But what if the user responds to the text message, then checks email before finally returning to the first app? This usage pattern is probably better considered to be two different sessions.

Fortunately we already have experience with other devices that support multitasking. For Android devices, Localytics have been recommending fifteen seconds as a reasonable time before which a session that was moved into the background should be closed. Short actions such as answering a wrong-number phone call, checking a stock ticker, or looking at an email inbox don’t disrupt the session but a conversation or composing a new email does.


So how to fit this model into an iPhone app?

iOS 4 provides a number of useful callbacks during the lifecycle of an iPhone app. Where instrumentation was previously concentrated in applicationDidFinishLaunching and applicationWillTerminate, now the bulk of the work happens in applicationWillEnterForeground and applicationDidEnterBackground.

The proper steps are:

  1. Open the session and upload data during applicationDidFinishLaunching. This opens the initial session.
  2. Close the session in applicationDidEnterBackground. This is also a good time to attempt to upload data.
  3. Attempt to resume the closed session (by calling the new ‘resume’ member of the LocalyticsSession object) in applicationWillEnterForeground. If less than 15 seconds have gone by, the session will be resumed otherwise a new session will be created. It is also recommended that data be uploaded at this time. If the upload at close time was successful then no data will be transmitted. If the previous upload failed, this is a good opportunity to try again.
  4. It is still recommended to close the session in applicationWillTerminate because there are still some cases where it is possible for the app to be terminated.
  5. (Optional) For users who want to override the 15 second default, this is accomplished by changing the value (in seconds) of backgroundSessionTimeout on the LocalyticsSession object.

This is how the finished result looks:

(void)applicationWillTerminate:(UIApplication *)application {
[[LocalyticsSession sharedLocalyticsSession] close];
[[LocalyticsSession sharedLocalyticsSession] upload];

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    [window makeKeyAndVisible];
    [[LocalyticsSession sharedLocalyticsSession] startSession:APP_KEY];

    // An example of changing the session timeout to one minute.
    [LocalyticsSession sharedLocalyticsSession].backgroundSessionTimeout = 60;

- (void)applicationDidEnterBackground:(UIApplication *)application {
    [[LocalyticsSession sharedLocalyticsSession] close];
    [[LocalyticsSession sharedLocalyticsSession] upload];

- (void)applicationWillEnterForeground:(UIApplication *)application {
    [[LocalyticsSession sharedLocalyticsSession] resume];
    [[LocalyticsSession sharedLocalyticsSession] upload];

For a more detailed explanation, see our iOS 4 Integration Guide.

Search the blog

Henry is the Co-founder and CTO at Localytics. He loves cars and his dog, Thane.