使用SwiftUI的新iOS 14生命周期在AppDelegate中访问AppState

问题描述

我正在使用iOS 14中的SwiftUI新应用程序生命周期。

但是,我被困在如何访问 AppDelegate 中的 AppState (单个事实来源)对象。 我需要 AppDelegate 在启动时运行代码注册通知didFinishLaunchingWithOptionsdidRegisterForRemoteNotificationsWithDevicetokendidReceiveRemoteNotification)等。

我知道@UIApplicationDelegateAdaptor,但后来我无法使用构造函数将对象传递到 AppDelegate 。我想反过来也行不通(在 AppDelegate 中创建 AppState ,然后在 MyApp 中访问它)。

@main
struct MyApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    @State var appState = AppState()
    
    var body: some Scene {
        WindowGroup {
            ContentView().environmentObject(appState)
        }
    }
}
class AppDelegate: NSObject,UIApplicationDelegate {
    func application(_ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        // access appState here...
        return true
    }

    func application(_ application: UIApplication,didRegisterForRemoteNotificationsWithDevicetoken devicetoken: Data) {
        // ...and access appState here
    }
}
class AppState: ObservableObject {
    // Singe source of truth...
    @Published var user: User()
}

感谢您的帮助。也许目前没有办法实现这一目标,我需要将我的应用程序转换为使用旧的UIKit生命周期?

解决方法

将共享实例用于 .item { display: contents; border: 1px solid black; }

AppState

因此您可以在任何地方使用它

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

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

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

    // ... other code
}
,

您是否有理由需要在应用程序委托中运行代码? 如果您使用的是新的应用生命周期,为什么不从WindowGroup.onChange()

触发代码
struct MyScene: Scene {
    @Environment(\.scenePhase) private var scenePhase
    @StateObject private var cache = DataCache()

    var body: some Scene {
        WindowGroup {
            MyRootView()
        }
        .onChange(of: scenePhase) { newScenePhase in
            if newScenePhase == .background {
                cache.empty()
            }
        }
    }
}

Apple Documentation Link

Managing scenes in SwiftUI by Majid