如何使用 SwiftUI 在 AppDelegate 中使用 EnvironmentObjects?

问题描述 投票:0回答:1

我正在尝试访问我的 AppDelegate 中的一些环境对象。我正在使用 addStateDidChangeListener 来查看 Firebase 用户的令牌是否有效。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    
    ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
    FirebaseApp.configure()
    Auth.auth().useAppLanguage()
    
    Auth.auth().addStateDidChangeListener { auth, user in
        
        if let user = user {
            
            user.getIDTokenResult { result, error in
                
                if let error = error {
                    print("Could not get the ID token result: \(error)")
                    self.sessionExpired()
                }
                
                if let expirationDate = result?.expirationDate {
                    
                    if Date() >= expirationDate {
                        print("Login session has expired.")
                        self.sessionExpired()
                    }
                    
                } else {
                    print("Could not get the expiration date from the ID token result.")
                    self.sessionExpired()
                }
                
            }
            
        } else {
            print("No user is signed in.")
        }
        
    }
    return true
}

如果令牌无效或用户不存在,我将显示一个 UIAlertController,表示他们需要再次登录。

func sessionExpired() {
    
    let alertController = UIAlertController(title: "Session Expired.", message: "Your login session has expired. Please sign in again.", preferredStyle: .alert)
    let okAction = UIAlertAction(title: "OK", style: .default) { action in
        
        FirebaseFunctions.signOutOfFirebase(saveAt: self.viewContext, with: self.environmentObjects, with: self.mapInformation, deleteCoreData: true)
        
    }
    alertController.addAction(okAction)
    
    UIApplication.shared.windows.first { $0.isKeyWindow }?.rootViewController?.present(alertController, animated: true)
    
}

当他们按下 OK 按钮时,我必须运行一个函数。这些函数称为

FirebaseFunctions.signOutOfFirebase(saveAt: self.viewContext, with: self.environmentObjects, with: self.mapInformation, deleteCoreData: true)
,它有3个参数。其中两个是环境对象,名为
environmentObjects
mapInformation
.

然而,每当调用该函数时,我都会收到错误消息:

致命错误:未找到类型为 EnvironmentObjects 的 ObservableObject。作为此视图的祖先,EnvironmentObjects 的 View.environmentObject(_:) 可能缺失。

这是我的应用程序生命周期开始的地方:

@main
struct MainApp: App {

@UIApplicationDelegateAdaptor var appDelegate: AppDelegate

@StateObject var environmentObjects = EnvironmentObjects()
@StateObject var networkMonitor = NetworkMonitor()
@StateObject var locationManager = LocationManager()
@StateObject var mapInformation = MapInformation()
@StateObject var popRoot = PopRoot()

... code

如何将环境对象传递给我的 AppDelegate?提前致谢!

firebase swiftui firebase-authentication appdelegate
1个回答
-1
投票

我确实认为

@EnvironmentObject
是用于在 views 之间传递数据的 SwiftUI 包装器。 我强烈建议您在此处查看 Paul 的 Hudson 文章How to use @EnvironmentObject to share data between views

注意:环境对象必须由祖先视图提供——如果 SwiftUI 找不到正确类型的环境对象,您将崩溃。这也适用于预览,所以要小心。

听起来很熟悉,对吧?

还有第二篇文章:什么是@EnvironmentObject属性包装器?我喜欢这个forced unwrapped optionals比较:

警告:当显示使用@EnvironmentObject 的视图时,SwiftUI 将立即在环境中搜索正确类型的对象。如果找不到这样的对象——也就是说,如果你忘记将它放在环境中——那么你的应用程序将立即崩溃。当您使用 @EnvironmentObject 时,您实际上是在承诺对象将在需要时存在于环境中,有点像使用隐式展开的可选对象。

如果您想查看一些代码示例,我会推荐 CodeWithChris YouTube 视频SwiftUI 应用程序中的数据流

附言。你能告诉我你想在哪里使用那些

@StateObject
变量吗?通常我在
private var myObject: Type = Type()
结构中实例化
@main
,然后使用
.environmentObject(myObject)
修饰符将它传递给视图。

© www.soinside.com 2019 - 2024. All rights reserved.