0% found this document useful (0 votes)
72 views

What Are iOS App Lifecycle Methods

I will explore differences in lifecycle in iOS 12 and 13 by testing the execution of those lifecycle methods in a simulator. This is what you will have learned by the end of the tutorial: ● What methods we can use to monitor lifecycle ● The sequence in which these methods are called ● How iOS version affects what methods are called

Uploaded by

rafiulalhasan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
72 views

What Are iOS App Lifecycle Methods

I will explore differences in lifecycle in iOS 12 and 13 by testing the execution of those lifecycle methods in a simulator. This is what you will have learned by the end of the tutorial: ● What methods we can use to monitor lifecycle ● The sequence in which these methods are called ● How iOS version affects what methods are called

Uploaded by

rafiulalhasan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

What Are iOS App Lifecycle Methods

Learn the nuances and difference between iOS versions


12- and 13+
we will learn about lifecycle of an iOS app. In addition, we will also explore differences in
lifecycle in iOS 12 and 13 by testing the execution of those lifecycle methods in a simulator. This
is what you will have learned by the end of the tutorial:

● What methods we can use to monitor lifecycle


● The sequence in which these methods are called
● How iOS version affects what methods are called

Let’s Start
We start with an almost empty project with one screen:
Our goal is to implement lifecycle methods and then see in what order they are called. In
addition, we also want to know what each method is best suited for. Before we start exploring
the code, let’s recap the states of any iOS app:

● Inactive — the app process is in foreground but it cannot respond to events.


● Active — the app process is in foreground and can respond to events.
● Background — the app process is in background, and performs some logic.
● Suspended — the app process is in background, but doesn’t perform any logic.
● Not running — the app process is not launched, meaning that it is neither in foreground
nor background.

We start with AppDelegate:

import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, willFinishLaunchingWithOptions
launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
print(#function)
return true
}

func application(_ application: UIApplication, didFinishLaunchingWithOptions


launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
print(#function)
return true
}

func applicationWillEnterForeground(_ application: UIApplication) {


print(#function)
}

func applicationDidBecomeActive(_ application: UIApplication) {


print(#function)
}

func applicationWillResignActive(_ application: UIApplication) {


print(#function)
}

func applicationDidEnterBackground(_ application: UIApplication) {


print(#function)
}
func applicationWillTerminate(_ application: UIApplication) {
print(#function)
}
}

Here we add the following methods:

● application(_:willFinishLaunchingWithOptions:) — called when the app is launched. At


the time the method is called, our app is in inactive state but it has already loaded the
main storyboard. In addition, state restoration (restoring screen hierarchy and UI state
from the last time a user used the app) hasn’t been started yet. Has the userInfo
parameter which we can use to determine the reason why the app was launched. For
example, if the app was launched to open a document at specific URL, we might want to
prevent state restoration from happening. To learn more about possible launch reasons,
visit the documentation.
● application(_:didFinishLaunchingWithOptions:) — gets called when our app was
launched and the state of the app was restored if needed. However, the UI isn’t shown
yet. Just like the previous method, also has the userInfo parameter. As Apple points out,
this is the last opportunity to perform logic relevant to that property.
● applicationWillEnterForeground(_:) — called in apps that do not support scenes.
Otherwise, it is replaced by its sceneWillEnterForeground(_:) covariant, which we will
explore in depth when examining the SceneDelegate later on. The method gets called
when the app is moving to an active state from the background.
● applicationDidBecomeActive(_:) — called in apps that do not support scenes. Otherwise,
it is replaced by its sceneDidBecomeActive(_:) covariant in the SceneDelegate. The
method is called when the app has entered the active state. At this moment, the UI has
been loaded, but not shown yet.
● applicationWillResignActive(_:) — called in apps that do not support scenes. Otherwise,
it is replaced by its sceneWillResignActive(_:) covariant in the SceneDelegate. The
method gets called when the app is interrupted by system alerts, phone calls, and so on.
We also trigger it when we dismiss the app using the Home button. We can use this
method to preserve unsaved data. For example, we might want to save the list of items
in the disk so that if the system kills the app, or we force quit it, the next time we launch it
we could see all the items displayed again.
● applicationDidEnterBackground(_:) — called in apps that do not support scenes.
Otherwise, it is replaced by its sceneDidEnterBackground(_:) covariant in the
SceneDelegate. The method is called when we move the app to the background. Here,
we need to make sure we stop timers, reduce the app’s memory usage and if necessary,
prepare for state restoration in case the app is terminated. In addition, after this method
returns, UIKit makes a snapshot of the latest UI of the app to display it in the app
switcher. Therefore, we need to hide from the UI user sensitive information, such as
passwords.
● applicationWillTerminate(_:) — this method is called when the app is about to be
terminated and removed from memory. It is always called for the apps that do not
support background mode. However, for the apps that do have background capability,
the method is usually not called since the app moves to the background state. On the
other hand, if the system decides to free up its memory and kills the app that is in
background, that method will be called.

With AppDelegate done, now let’s inspect the SceneDelegate:

import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

var window: UIWindow?

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options


connectionOptions: UIScene.ConnectionOptions) {
print(#function)
}

func sceneDidDisconnect(_ scene: UIScene) {


// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is
discarded.
// Release any resources associated with this scene that can be re-created the next time
the scene connects.
// The scene may re-connect later, as its session was not necessarily discarded (see
`application:didDiscardSceneSessions` instead).
print(#function)
}

func sceneDidBecomeActive(_ scene: UIScene) {


// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the
scene was inactive.
print(#function)
}

func sceneWillResignActive(_ scene: UIScene) {


// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
print(#function)
}

func sceneWillEnterForeground(_ scene: UIScene) {


// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
print(#function)
}

func sceneDidEnterBackground(_ scene: UIScene) {


// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough
scene-specific state information
// to restore the scene back to its current state.
print(#function)
}

Here we have these methods:

● scene(_:willConnectTo:options:) — called when the app requests the user interface. As


explained in Scenes documentation, a scene is contains a window and view controllers.
So essentially, this method is called when we add a scene to the application. Most apps
have only one scene, so this method will be called once in such cases. Inside the
method, we configure the hierarchy and set the root view controller for the window. For
example:

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

var window: UIWindow?

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options


connectionOptions: UIScene.ConnectionOptions) {

guard let windowScene = (scene as? UIWindowScene) else { return }

window = UIWindow(windowScene: windowScene)

let rootNavigationController = RootNavigationController(


rootViewController: ItemListViewController()
)
window?.rootViewController = rootNavigationController
window?.makeKeyAndVisible()
}
}
● sceneWillEnterForeground(_:) — just as its non-scene counterpart
applicationWillEnterForeground(_:), the method is called when the app is in
foreground-inactive state and is preparing to be shown to the user.
● sceneDidBecomeActive(_:) — identically to applicationDidBecomeActive(_:), the method
is called when the UI has entered the foreground-active mode and the UI has been
loaded, but not yet shown.
● sceneWillResignActive(_:) — just as its non-scene covariant
applicationWillResignActive(_:), the method is called when the app is interrupted by a
phone call, or a system alert. We also trigger it by tapping on the Home button.
● sceneDidEnterBackground(_:) — called when the app is no longer on the screen. As
Apple suggests, we can use this method to reduce a scene’s memory usage and hide
sensitive user information from the screen, since after this method returns, UIKit will
create a snapshot of the UI and show it in in the app switcher.
● sceneDidDisconnect(_:) — called when a user removes the scene from the app by
closing it in the app switcher. The system can also disconnect a scene to free memory
space if needed.

With method descriptions done, now let’s examine the sequence and conditions based on which
these methods are called.

To see the name of each method that was called, we include the print(#function) command
inside each of the methods we added in the AppDelegate and SceneDelegate:

import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions:


[UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {

print(#function)

return true
}

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:


[UIApplication.LaunchOptionsKey: Any]?) -> Bool {

print(#function)

return true
}

func applicationWillEnterForeground(_ application: UIApplication) {


print(#function)
}

func applicationDidBecomeActive(_ application: UIApplication) {


print(#function)
}

func applicationWillResignActive(_ application: UIApplication) {


print(#function)
}

func applicationDidEnterBackground(_ application: UIApplication) {


print(#function)
}

func applicationWillTerminate(_ application: UIApplication) {


print(#function)
}

import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

var window: UIWindow?

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options


connectionOptions: UIScene.ConnectionOptions) {
print(#function)
}

func sceneDidDisconnect(_ scene: UIScene) {


print(#function)
}

func sceneDidBecomeActive(_ scene: UIScene) {


print(#function)
}

func sceneWillResignActive(_ scene: UIScene) {


print(#function)
}
func sceneWillEnterForeground(_ scene: UIScene) {
print(#function)
}

func sceneDidEnterBackground(_ scene: UIScene) {


print(#function)
}

Now we can easily test the execution of these methods. First, we will test it on iOS 13+
Simulator, then on iOS 12 one.

Testing on iOS 13+


● Launch app:

● Close app:
● Move the app to background instead of closing:

● Return to the app from the background:


Now let’s do the same with an iOS 12 Simulator.

Testing on iOS 12
● Launch app:
● Close app:
● Move the app to background instead of closing:
● Return to the app from the background:
Examining the difference
As we see above, the execution differs in some of the phases.

1. When the app was launched on iOS 13+, these methods were run:
● application(_:willFinishLaunchingWithOptions:),
● application(_:didFinishLaunchingWithOptions:),
● scene(_:willConnectTo:options:),
● sceneWillEnterForeground(_:),
● sceneDidBecomeActive(_:).

On iOS 12, however, we saw only three methods running:

● application(_:willFinishLaunchingWithOptions:),
● application(_:didFinishLaunchingWithOptions:),
● applicationDidBecomeActive(_:).

The most noticeable difference here is that the applicationWillEnterForeground(_:) method


wasn’t called on iOS 12, even though the sceneWillEnterForeground(_:) is a replacement for it
on iOS 13+ and it was executed on the iOS 13 device.
2. When the app was terminated on iOS 13+, these methods were run:

● sceneWillResignActive(_:)
● sceneDidDisconnect(_:)
● applicationWillTerminate(_:)

On iOS 12, we saw these methods executing:

● applicationWillResignActive(_:)
● applicationDidEnterBackground(_:)
● applicationWillTerminate(_:)

Here we notice that on iOS 12, the app was moved to background prior to getting terminated,
while on iOS 13+ the covariant method sceneDidEnterBackground(_:) was not called.

3. On iOS 13+, when the app was simply dismissed instead of terminated, these methods were
run:

● sceneWillResignActive(_:)
● sceneDidEnterBackground(_:)

On iOS 12:

● applicationWillResignActive(_:)
● applicationDidEnterBackground(_:)

In this phase we do not notice any difference since as the official documentation says, the
application methods of iOS 12 and prior were replaced by the scene ones of iOS 13 and
onward.

4. On iOS 13+, when we moved the app back to active state from the background, we saw the
following methods printed:

● sceneWillEnterForeground(_:)
● sceneDidBecomeActive(_:)

On iOS 12:

● applicationWillEnterForeground(_:)
● applicationDidBecomeActive(_:)

Just like in previous step, here we also have no difference of execution.

Resources
The source code is available on GitHub.

You might also like