Accessing the app life cycle within a SwiftUI app

Accessing the app life cycle within a SwiftUI app

Learn how to have access to the application life cycle of a SwiftUI-based app.

There are procedures within the execution of an application that must be executed at a specific moment of its life-cycle, for example when the app finishes launching, when it goes to the background, or right before it is closed.

Within the App protocol in SwiftUI, the launch options are limited in defining the entry point of our application. In order to access different moments of the life cycle of the application we must use an object that conforms to the UIApplicationDelegate protocol, which is defined as the default entry point of a UIKit-based application.

In this reference article, we will disclose how to work with the life cycle of a SwiftUI app.

Application Delegate

The protocol App is used to define the entry point of a SwiftUI application, instead of creating a class that conforms to the UIApplicationDelegate protocol.

We can recreate the AppDelegate class conforming it to the UIApplicationDelegate protocol to be able to access the application life cycle methods on a SwiftUI application.

In the same file where is defined the entry point of your SwiftUI application, create the AppDelegate class as the following:

// Creating the AppDelegate class
class AppDelegate: NSObject, UIApplicationDelegate {
    
    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        print("Application launched!")
        return true
    }
    
}

Now use the @UIApplicationDelegateAdaptor property wrapper to indicate that the app should use our AppDelegate class to handle app delegate callbacks.

@main
struct CatsRemindersApp: App {

    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
You can also make the AppDelegate class conform to the ObservableObject protocol and access it through the app environment in your views.

Scene Phase

Another way to have access to the current state of the application is by reading the scenePhase environment value.

@Environment(\.scenePhase) private var scenePhase

It provides you with three different values to represent if the scene is currently active, inactive, or in the background. In the following example, we use the onChange modifier to keep track of the scene phase changes and print different messages on the terminal.

@main
struct CatsRemindersApp: App {
    
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    @Environment(\.scenePhase) private var scenePhase
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onChange(of: scenePhase) {
                    
                    switch scenePhase {
                    case .background:
                        print("Scene in background")
                    case .inactive:
                        print("Scene is inactive")
                    case .active:
                        print("Scene in active")
                    @unknown default:
                        print("Phase not handled")
                    }
                    
                }
        }
    }
}