如何使用@EnvironmentObject 在 SwiftUI 中的 AppDelegate 和 SceneDelegate/Views 之间共享数据

AnE*_*Erd 7 appdelegate swiftui

在 SwiftUI 5.1 中,我想使用 AppDelegate 创建一个 userData 对象。userData 还将包含 BLE 广告数据,这些数据也将从 AppDelegate 更新。这些数据应该可供 UI 使用以显示这些值。

在 AppDelegate 我使用

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    private var centralManager : CBCentralManager!
    var userData: UserData!

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        userData = UserData()

        return true
    }
Run Code Online (Sandbox Code Playgroud)

在 SceneDelegate 我想传递给视图使用

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    @EnvironmentObject var userData: UserData

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
        // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
        // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).

        // Use a UIHostingController as window root view controller
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView:
                BeaconList().environmentObject(userData)
            )

            self.window = window
            window.makeKeyAndVisible()
        }
    }
Run Code Online (Sandbox Code Playgroud)

编译工作正常,但运行代码时我得到

线程 1:致命错误:在 View.body 之外读取 EnvironmentObject

如果我删除

.environmentObject(用户数据)

我得到

线程 1:EXC_BAD_INSTRUCTION(代码=EXC_I386_INVOP,子代码=0x0)

本质上,我试图从 AppDelegate 创建和更新 userData 对象,并从 SceneDelegate 显示并在下面查看。

我该如何实施?

rra*_*ael 6

也许您可以使用UIApplication.shared.delegate来获取 AppDelegate 访问用户数据:

class AppDelegate: UIResponder, UIApplicationDelegate {

    var userData: UserData!

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        userData = UserData()
        return true
    }
}
Run Code Online (Sandbox Code Playgroud)
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
        // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
        // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).

        let userData = (UIApplication.shared.delegate as! AppDelegate).userData

        // Use a UIHostingController as window root view controller
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(userData))
            self.window = window
            window.makeKeyAndVisible()
        }
    }
Run Code Online (Sandbox Code Playgroud)