Bye Bye AppDelegate! SwiftUI App Life Cycle
Now XCode 12 introduces two options for app life cycle. When you create new project by xcode then you can see Life Cycle dropdown to choose.
UIKit AppDelegate or SwiftUI
Once you create a project with the above setting, you project in xcode will look like this:
You can see that there are two swift files — one SwiftUILifeCycleAppApp.swift & ContentView.swift
ContentView.swift is the first view file which renders on the window where SwiftUILifeCycleAppApp.swift is your main entry point in the app just like AppDelegate.
Let’s dive into depth of SwiftUILifeCycleAppApp.swift
There is a struct ‘SwiftUILifeCycleAppApp’ which confirms to App protocol and in the body part, ContentView is added on the app Window. That’s it, nothing else in the file. You can see, it is so light weighted. One more thing, you can see @main just above the struct ‘SwiftUILifeCycleAppApp’. It tells to the system that it is main entry point of the app.
Now, you have lots of questions that where we’ll do lots of stuff which we do in AppDelegate’s didFinishLaunchWithOptions callback and app life cycle callback events methods etc. Don’t worry 😉 we’ll discuss all the these here.
App States Callbacks
In iOS 14, Apple provided ScenePhase to track app states. You project can have multiple scene, but here, we have only one scene. Scene’s state is tracked in the environment, and so we created
@Environment property to access the current value, and then used the
onChange(of:)modifier to listen to any changes in the state.
For more details, you should read apple document.
In the UIKit approach, we handles all the deeplink urls by
application(_:open:options:) delegate callback method and route this incoming url to the destination path.
But in the SwiftUI, we can handle incoming urls by attaching the
onOpenURL modifier to the top-most scene in your app. It returns the incoming url in closure (refer line numbers — 17 to 20 in below screenshot).
For basic initialization or if you are using some third parties and need to setup on app launch just like in AppDelegate’s didFinishLaunchWithOptions method, then you can do in init method of struct ‘SwiftUILifeCycleAppApp’ (refer line numbers — 14 to 16 in below screenshot).
AppDelegate in SwiftUI
If you have some requirements which can not be fulfilled by this approach and you have need of AppDelegate then SwiftUI provides a way to use AppDelegate within SwiftUI life cycle by using
@UIApplicationDelegateAdaptor gives the option of using UIApplicationDelegate methods that are traditionally used in UIKit applications.
First add a file to create AppDelegate class e.g. ‘MyAppDelegate.swift’ then create a class of ‘MyAppDelegate’ which inherited from ‘UIResponder’ and confirms to ‘UIApplicationDelegate’ and then add didFinishLaunchWithOptions method.
After creating AppDelegate, now attach it with struct ‘SwiftUILifeCycleAppApp’ main entry point by
@UIApplicationDelegateAdaptor property wrapper.
First scene init method calls and then AppDelegate’s didFinishLaunchWithOptions method calls.
So this was just basic about new SwiftUI life cycle update. It is so light weighted. Also apple provides a way to use AppDelegate with SwiftUI life cycle. That’s very good.
Here is link of full source code: https://github.com/sanjeevworkstation/SwiftUILifeCycleApp
Thank You. Happy coding! 👍