Swiftui App Life Cycle Ios14 Where to Put Appdelegate Code

SwiftUI app life cycle iOS14 where to put AppDelegate code?

Here is a solution for SwiftUI life-cycle. Tested with Xcode 12b / iOS 14

import SwiftUI
import UIKit

// no changes in your AppDelegate class
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
print(">> your code here !!")
return true
}
}

@main
struct Testing_SwiftUI2App: App {

// inject into SwiftUI life-cycle via adaptor !!!
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

var body: some Scene {
WindowGroup {
ContentView()
}
}
}

How to add code to AppDelegate using SwiftUI Life Cycle

The init might be too early, try in app delegate as follows

import GoogleMobileAds

class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {

GADMobileAds.sharedInstance().start(completionHandler: nil) // << here !!
return true
}
}

@main
struct YourApp: App {

@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

var body: some Scene {
WindowGroup {
ContentView()
}
}
}

Accessing AppState in AppDelegate with SwiftUI's new iOS 14 life cycle

Use shared instance for AppState

class AppState: ObservableObject {
static let shared = AppState() // << here !!

// Singe source of truth...
@Published var user = User()
}

so you can use it everywhere

struct MyApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
@StateObject var appState = AppState.shared

// ... other code
}

and

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
// ...and access appState here

AppState.shared.user = ...
}

How do you migrate to the new SwiftUI App Protocol?

You need to follow these steps to migrate a SwiftUI application to the new App life cycle:

  1. Create a new App struct and add the @main annotation:
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}

  1. Remove the @main annotation from AppDelegate.

  2. Remove Scene Configuration from Info.plist:

Sample Image


  1. (Optionally) Move AppDelegate/SceneDelegate methods:
  • SwiftUI app life cycle iOS14 where to put AppDelegate code?
  • Is there any way to call SceneDelegate methods in iOS 14 app life cycle?

  1. Now you can remove the AppDelegate and SceneDelegate classes from the project (first make sure the app is indeed working as expected).

How to Listen to new SwiftUI Lifecycle Methods in iOS 14?

You can get the APP LAUNCHING STATES (formerly done in AppDelegate) by being notified from the global environment variable and its property ".scenePhase" like so:

// CREATE SOME APP LAUNCHING STATES LIKE WE HAD IN APPDELEGATE

@main
struct NewAppLifeCycleApp: App {

@Environment(\.scenePhase) var scenePhase

var body: some Scene {
WindowGroup {
ContentView()
}
.onChange(of: scenePhase) { newScenePhase in
switch newScenePhase {
case .active:
print("App is active")
case .inactive:
print("App is inactive")
case .background:
print("App is in background")
@unknown default:
print("Interesting: Unexpected new value.")
}
}
}
}

If you want to integrate some code at a very early stage of your app, you can just add an init-function:

// EASY WAY TO INTEGRATE SOME CODE INTO 
// VERY EARLY STAGE OF APP INIT

@main
struct ColorsApp: App {

// Add an init method to add code
init() { print("My App is starting") }

var body: some Scene {
WindowGroup {
ContentView()
}
}

Where to configure Firebase in my iOS app in the new SwiftUI App life cycle without AppDelegate and SceneDelegate?

There are three approaches for initialising third part frameworks in the new SwiftUI life cycle:

Using the old life cycle model

You can still use the old life cycle model:

Option 1: Use the UIKit App Delegate life cycle

When creating a new SwiftUI project, you can choose the old life cycle model. This will create an AppDelegate and a SceneDelegate as before. Not as fancy as using SwiftUI all the way, I admit - but definitely the easiest and most straightforward way.

Setting up a SwiftUI 2.0 project with the traditional AppDelegate Life Cycle

Using the new life cycle model

If you want to use the new life cycle model, use either one of the following approaches.

Option 2: Use the App's initialiser

You can override the default initialiser of your App class, like this:

import SwiftUI
import Firebase

@main
struct SO62626652_InitialiserApp: App {

init() {
FirebaseApp.configure()
}

var body: some Scene {
WindowGroup {
ContentView()
}
}
}

Option 3: Use @ UIApplicationDelegateAdaptor

In you App class, define a property that holds a reference to your AppDelegate, and let SwiftUI inject the AppDelegate using the @ UIApplicationDelegateAdaptor property wrapper, like this:

import SwiftUI
import Firebase

@main
struct SO62626652_AppDelegateAdaptorApp: App {
@UIApplicationDelegateAdaptor private var appDelegate: AppDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}

class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
FirebaseApp.configure()
return true
}
}


Related Topics



Leave a reply



Submit