The execution states of an iOS application

Chinthaka Perera
9 min readSep 6, 2019

--

When you are using an iOS application you have experienced some app states like,

  • App is visible on the screen.
  • App is on background.
  • App isn’t visible on the screen or background (Multitasking UI).

But do you know, Apple has defined 5 execution states of an iOS application. Transition between these states are done by the OS by considering the user’s action.

The execution states are can be listed as below,

  • Not Running
  • Inactive
  • Active
  • Background
  • Suspended

Among these 5 app states only the Inactive, Active and Background states and considered as the running states.

But why? OK. Let’s explain one by one as below,

Not Running

This is the basic app state of an iOS application.

  • This means the app has not launched yet.
  • Or the app has been terminated by the user.
  • Also there is a possibility to the app has been terminated by the OS (This will be explained at the Suspended state explanation.).

So, if the app is not available on the screen or background among the other apps, that means the app is on the Not Running state.

Inactive

This state occurs while the app transitioning to the Active state or transitioning from the Active state on the foreground. This means the this state occurs only while transitioning from one state to another.

Additionally to the app state transitions the Inactive app state can be occurred while running the app if a phone call is received or activated siri.

These are the app states transitions that transit through the Inactive state,

  • Not Running -> Inactive -> Active
  • Active -> Inactive -> Background
  • Background -> Inactive -> Active

If you are holding your app on the multitasking UI, the OS keeps the app on the Inactive state and transit to the next state by considering the next user’s action on the app.

What are the action that can be taken place from the multitasking UI,

  • Open an another app from multitasking UI and the app goes to background.
  • Directly move the app to background.
  • Screen off by click on power button and the app goes to background. (After that if you on the screen, the app will come to the foreground automatically.)
  • Swipe the app and terminate.
  • Open the app again.

At the Inactive app state the application isn’t receiving any events (The UI also not accessible at this state. So, the UI events are not also available.). But the app can continuously run the code on the task which is executing.

Active

This is the main execution state of an iOS application. The app is running on foreground and the UI is accessible. It receives any events and executes the code.

As shown in the Inactive app state explanation, Transition from any of app state to this state occurs only through the Inactive app state.

Background

Once the app moved to background it will be transited to the Background state. In this state, still the app can execute the code and receive the events (Not UI events).

But in a limited time period the OS automatically moves the app to the Suspended state and stops execution of code. When you are using iOS 12, the app remain on the Background state for around 180 seconds. But it can be differ on other iOS versions. This is given to facilitate us to finish any task which was executing. But we can extend the execution time in the background by using beginBackgroundTask(expirationHandler:) or

beginBackgroundTask(withName:expirationHandler:).

Suspended

This is the app state when your app is on background after the app has been transited from the Background state by the OS. At this app state, your app remains on the memory. But not executing any code.

Since the app is not executing the code, the battery life is not affected by the application. But if any running app needs memory and the system is low on memory, the OS will terminate some suspended apps to free the memory.

But the transition to move to the Suspended state or terminate the app by the system from the Suspended state are not notified by the OS.

Now Let’s have a look at the sequence of the app state transition,

Figure 1

You can see the Active state is only accessible through the Inactive app state. And the state transition through the Suspended has been indicated by doted arrows, as it is not actually notified by the OS.

Now it’s the time to handle these app state transition in our app.

Why we need to handle the app state transitions ?

As an iOS developer it is important to familiar with the app state transitions and handle those.

Why am I telling that,

Just image,

  • You are calling an API and retrieving some data from your backend and you are using a timer for execute that. What if the app goes background and after some time app comes to the foreground again ?
  • You are using CoreData and you have some dirty objects to be saved. But the user terminates the app ?
  • You need to download some files whether the app on foreground or background ?

Above are some examples that you can be faced with a confusion about data lost or task executions.

So, you have to have a good understand on handing the app state transitions.

What are the ways to handle the app state transitions ?

1. Functions in the AppDelegate:

Have you heard about the AppDelegate or are you familiar with that. AppDelegate is the place which is getting notified about the app state transitions by the OS.

When you create a project by using the Xcode, it will generate the AppDelegate and it has some functions that can be used to handle the app state transitions.

Let’s check the AppDelegate which is generated when you create an iOS project by Xcode using the Single View App template,

Figure 2

Okay. Let me explain the content of the AppDelegate first,

  • UIKit -

UIKit (https://developer.apple.com/documentation/uikit) is the framework provided by the SDK to facilitate us to implement screens and handle the UI events.

  • @UIApplicationMain -

UIApplicationMain (https://developer.apple.com/documentation/uikit/1622933-uiapplicationmain) is a function. Once it is called, the system creates a singleton instance of UIApplication and creates a application delegate (Sets AppDelegate as the application delegate) for us.

Objective C creates a main.m class and it has a main method. This UIApplicationMain method is called inside this main method and all of that is generated by the Xcode. But now when you are using Swift, the Xcode is not generating a main.swift class and instead of that it gives us the @UIApplicationMain attribute (https://docs.swift.org/swift-book/ReferenceManual/Attributes.html).

Using this attribute, it indicates the AppDelegae as our application delegate and creates the singleton instance of the UIApplication.

If you want to have a main.swift class, just delete the @UIApplicationMain attribute and create a main.swift class. Then add the main method and call the UIApplicationMain method from it.

  • UIApplication -

UIApplication (https://developer.apple.com/documentation/uikit/uiapplication) singleton instance is used to execute the tasks or set configurations, which are interacted with the system.

- Register for push notifications.

- Execute a background task if you are executing a long running task even the app on background.

- Open an URL using Safari.

- Open a custom setting from the Settings app. Etc…

Above are some of points that we need to use the UIApplication.

  • UIApplicationDelegate -

UIApplicationDelegate (https://developer.apple.com/documentation/uikit/uiapplicationdelegate) defines the functions that we are using in the application delegate (AppDelegate) to handle the app behaviors and manage system notifications.

  • window -

The app contents have been laid on a UIWindow (https://developer.apple.com/documentation/uikit/uiwindow) object. You have this main window object which is created by Xcode. Also you can create additional windows if you want.

  • didFinishLaunchingWithOptions function -

This function is called by the OS when the launch process is almost done. (To launch the app, this function execution is need to be completed.) You can use this function and do the configurations you need, when the app is running.

Like,

- Create a Sqlite database for local data storage.

- Configure for data analytics. Etc…

If you check the UIApplicationDelegate documentation you can see another function called, willFinishLaunchingWithOptions. This is called by the OS after the app launch process began and also, before the app state transition begin.

Please note that you have to complete the execution of these methods within given limited time period by the system. If not, the app won’t launch.

  • The rest of other functions -

Those are the functions which are called by the OS to notify after transit between the app states.

Additionally to these app state transition related function you can see the other functions to handle app behaviors and system interactions in the UIApplicationDelegate documentation.

What is the sequence of these function calls for each app state transitions ?

Now let’s have a look for the sequence of the function calls by the OS according to the app state transitions,

  • Not Running -> Active:

When you launch an app that has not launched yet or terminated, it transit from Not Running to Active state.

The full path,

Not Running -> Inactive -> Active

Once you launched the app, the OS will notify us the launch progress by calling willFinishLaunchingWithOptions and didFinishLaunchingWithOptions functions in the AppDelegate.

Then regarding the app state transition, the OS calls following function,

- applicationDidBecomeActive

applicationDidBecomeActive function

When this is called, your first screen of the app has been visualized on the device. And this is the only function that is called by the OS to notify the app state transition after an app launched.

  • Active -> Background:

When you send a foreground running app to background, it transit from Active to Background state.

The full path,

Active -> Inactive -> Background

Once you tap on the home button or send the app to the multitasking UI, the app state transit to the Inactive state.

Then regarding the app state transition, the OS calls following function,

- applicationWillResignActive

applicationWillResignActive function

You can use this function to stop any foreground related tasks if you want. Let’s say you are using a timer and you can use this function to stop it.

After that you can send the app to the background and then the following function is called by the OS,

- applicationDidEnterBackground

applicationDidEnterBackground function

Now your app is running on the background. But keep in mind. Your app will transit to the Suspended state in a limited time period from here without any notification from the system.

So,

you can begin background task from here if you need to perform a long running task on background.

or,

you can save the dirty objects if you are using CoreData.

  • Background -> Active:

When you are sending an app from background to foreground, it transit from Background to Active state. (Also please note that the suspended apps are also transit through the same sequence and we are not notified the state transition from Suspended to Background state.)

The full path,

Background -> Inactive -> Active

When the app transit from Background/ Suspended to Inactive state, the following function is called.

- applicationWillEnterForeground

applicationWillEnterForeground function

After that the following function is called by the OS to notify that the app has entered to Active state,

- applicationDidBecomeActive

applicationDidBecomeActive function

In here you can reschedule your foreground related timer.

If you take the app to the multitasking UI from foreground and then again to the Active state, the OS directly calls the above function. (applicationDidBecomeActive)

  • Active -> Not Running:

When you are killing an app from foreground, the app transit from Active to Not Running state.

The full path,

Active -> Inactive -> Not Running

Please note that the method call sequence is as same as the transition from Active to Background. In Additionally the OS calls the following function at last,

- applicationWillTerminate

applicationWillTerminate function

You can kill an app even it is on background. So, you take the app to the multitasking UI and swipe on it. Nothing called before the app comes to the multitasking UI. After you swipe, the OS directly calls the above function. (applicationWillTerminate)

2. Notifications provided by the system:

You can use the following Notifications which have been provided by the system at anywhere you want by registering them. Those are notified after the each equivalent Delegate function function is called.

- UIApplicationDidEnterBackgroundNotification

- UIApplicationWillEnterForegroundNotification

- UIApplicationDidFinishLaunchingNotification

- UIApplicationDidBecomeActiveNotification

- UIApplicationWillResignActiveNotification

- UIApplicationWillTerminateNotification

The End

--

--