With the launch of SwiftUI 2 at WWDC 2020, Apple introduced a new App Life Cycle (App). Instead of an AppDelegate.
Application gateways
When creating a new SwiftUI application, the main class of the application looks like this:
import SwiftUI
@main
struct SwiftUIApp: App {
var body: some Scene {
WindowGroup {
ContentView()}}}Copy the code
Initialize the configuration and third-party libraries
In most cases, the application starts with initialization: default data configuration, SDKS, third-party libraries, and so on.
When using AppDelegate in application (_ application: didFinishLaunchingWithOptions launchOptions:) operation:
func application(_ application: UIApplication.didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// configs...
print("Application is starting...")
return true
}
Copy the code
In the life cycle of the App:
import SwiftUI
@main
struct SwiftUIApp: App {
init(a) {
// configs...
print("Application is starting...")}var body: some Scene {
WindowGroup {
ContentView()}}}Copy the code
Handles the application lifecycle
Sometimes we need to deal with operations based on the life cycle of the application. For example, we want to refresh the data when the application is active, or cache the data when the application is in background state.
In the AppDelegate, realize applicationWillResignActive, applicationDidBecomeActive, applicationWillEnterForeground, ApplicationDidEnterBackground, applicationWillTerminate method
In the App, Apple provides a new API: ScenePhase
SwiftUI tracks the state of the application. You can use the @Environment attribute wrapper to get the current value and use.onchange (of: Perform 🙂 to listen for changes.
import SwiftUI
@main
struct SwiftUIAppApp: App {
@Environment(\.scenePhase) var scenePhase
var body: some Scene {
WindowGroup {
ContentView()
}
.onChange(of: scenePhase) { phase in
switch phase {
case .active:
print("Application is active")
case .inactive:
print("Application is inactive")
case .background:
print("Application is background")
default:
print("unexpected value.")}}}}Copy the code
It’s worth noting that other locations in the app can also use this method of listening:
import SwiftUI
struct ContentView: View {
@Environment(\.scenePhase) private var scenePhase
var body: some View {
Text("Hello, world!")
.padding()
.onChange(of: scenePhase, perform: { value in
if value = = .active {
print("Application view is active...")}})}}Copy the code
Isn’t that nice? Imagine the process of writing a notice…
Notice: I don’t want face
Dealing with Deep Link
In the AppDelegate, implement application(_:open:options:) to process the URL
In the App, use the.onOpenURL modifier.
import SwiftUI
@main
struct SwiftUIAppApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.onOpenURL(perform: { url in
print("Received URL: \(url)")})}}}Copy the code
Similarly, you can apply this modifier elsewhere in the application. That means you can handle deep links anywhere. Of course, the premise is that when the application starts, the implementation position must be in the active state
import SwiftUI
struct ContentView: View {
var body: some View {
Text("Hello, world!")
.onOpenURL(perform: { url in
print("Received URL: \(url)")}}}Copy the code
Although universal Links should be used after iOS 9, it is more secure. But that doesn’t deny the convenience of onOpenURL. We can still define and use it.
The terminal invokes the App via deep link:
xcrun simctl openurl booted
your url
I don’t care. I’m just going to use an AppDelegate
So when you create the project, you chooseAppDelegate
Cough up. A little bit…
The life cycle of an App is not a complete substitute for an AppDelegate, and in some cases we still need to use an AppDelegate or its methods. For example: SDK callback, third-party library Extension, Method Swizzling, etc.
Provides a comprehensive a variety of reasons, Swift AppDelegate method, which is connected with the App: @ UIApplicationDelegateAdaptor
import SwiftUI
class AppDelegate: NSObject.UIApplicationDelegate {
func application(_ application: UIApplication.didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
print("Application didFinishLaunchingWithOptions")
return true
}
func application(_ application: UIApplication.willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
print("willFinishLaunchingWithOptions")
return true}}@main
struct SwiftUIAppApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
init(a) {
print("Application is starting...")}var body: some Scene {
WindowGroup {
ContentView()}}}Copy the code
conclusion
SwiftUI 2’s new app entry is designed, in part, to simplify app launch. At a glance, it is very simple, but also convenient for others to take over when easier to be clear at a glance, easy to maintain. All in all, it’s good.
There are also some disadvantages. At present, compared to the AppDelegate, the App is not perfect, and some functions still rely on interaction with the AppDelegate. There are few official demos, and most of them have to be worked out on their own. Look forward to the follow-up official website supplement and update! And it’s only the beginning, after all. Swift went through five versions before settling down. SwiftUI is young by comparison.
Demo
Github
Reference:
- The Ultimate Guide to the SwiftUI 2 Application Life Cycle