With iOS 13 supporting SwiftUI, iOS 14 has introduced an app lifecycle. Developers today are trying to rethink their app design from the erstwhile AppDelegate and SceneDelegate methods to the declarative world of SwiftUI. While this declarative way of life makes app-building easier, it poses a common dilemma: Where does all that old AppDelegate stuff go in a SwiftUI app?
This article highlights the fundamental differences between traditional and SwiftUI lifecycles and talks about the transition of AppDelegate logic into a SwiftUI project.
The entry point for your app is always the @main struct which conforms to App protocol in SwiftUI app lifecycle. Here's an example:
import SwiftUI
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
The App protocol does not require that you use an AppDelegate or SceneDelegate given that a declarative structure is laid out for the entry point into your app. Still, some use cases require AppDelegate functionalities like:
It is still possible to use AppDelegate for any legacy functionality with the new SwiftUI lifecycle. Below are the multiple methods of integrating AppDelegate code into a SwiftUI app.
1. Using the @UIApplicationDelegateAdaptor Property Wrapper
SwiftUI itself has provided the @UIApplicationDelegateAdaptor property wrapper to serve between the two lifecycle approaches, new and old or, more appropriately, traditional AppDelegate.
Step-by-Step Example:
1. Just create an AppDelegate class much like what you've done for any UIKit app:
import UIKit
class AppDelegate: NSObject, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
print("AppDelegate: App launched")
return true
}
func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
print("AppDelegate: Registered for remote notifications")
}
}
2. Now, attach your AppDelegate to your SwiftUI App struct using @UIApplicationDelegateAdaptor:
import SwiftUI
@main
struct MyApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
Your AppDelegate class is now the handler for many app lifecycle events, such as push notification registrations and launch configuration.
2. Working directly with UIResponder and UIApplicationDelegate
If you have an app that relies extensively on AppDelegate logic, you may ignore the SwiftUI lifecycle altogether and dive into the more traditional UIKit approach below:
It shouldn't be done unless you want to go all the way back to UIKit compatibility reasons.
3. Handling SceneDelegate Code
If your app was using SceneDelegate, then you could replicate similar functionality in SwiftUI using onChange modifiers and environment values like scenePhase.
Example: Using onChange to Detect Scene Changes
import SwiftUI
@main
struct MyApp: App {
@Environment(\.scenePhase) private var scenePhase
var body: some Scene {
WindowGroup {
ContentView()
.onChange(of: scenePhase) { newPhase in
switch newPhase {
case .active:
print("App is active")
case .inactive:
print("App is inactive")
case .background:
print("App is in the background")
default:
print("App is in an unknown state") // Better to handle default case
}
}
}
}
}
This handles all state changes without the use of a SceneDelegate.
Although the app lifecycle in SwiftUI is fairly sufficient for most cases, AppDelegate should be used in the following situations:
SwiftUI app lifecycle is going to be the future of iOS, but AppDelegate will always be here for legacy features and third-party integrations. Incorporate @UIApplicationDelegateAdaptor to include AppDelegate logic into your SwiftUI apps declaratively with no need to compromise any of the benefits a declarative structure grants.
That means you can create apps that are contemporary, functional, and poised to accommodate future improvements.
Ready to transform your business with our technology solutions? Contact Us today to Leverage Our iOS Expertise.