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

ars1skjm  于 2023-03-24  发布在  Swift
关注(0)|答案(1)|浏览(161)

我正在尝试访问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个参数。其中两个是环境对象,名为environmentObjectsmapInformation
然而,每当调用该函数时,我都会得到错误:
致命错误:未找到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?提前感谢!

bpsygsoo

bpsygsoo1#

我确实认为@EnvironmentObject是一个SwiftUI Package 器,用于在视图之间传递数据。
注意:环境对象必须由祖先视图提供-如果SwiftUI找不到正确类型的环境对象,您将崩溃。这也适用于预览,所以要小心。
听起来很熟悉,对吧?
还有第二条:What is the @EnvironmentObject property wrapper?我喜欢这个 * 强制解包可选 * 比较:
警告:当显示使用@EnvironmentObject的视图时,SwiftUI将立即在环境中搜索正确类型的对象。如果找不到这样的对象-即如果您忘记将其放置在环境中-则您的应用将立即崩溃。当您使用@EnvironmentObject时,您实际上是在保证对象在需要时会存在于环境中,有点像使用隐式展开的可选项。
如果你想看一些代码示例,我推荐CodeWithChris YouTube视频Data Flow in a SwiftUI App
PS.请问你想在哪里使用这些@StateObject变量?通常我在@main结构中示例化private var myObject: Type = Type(),然后使用.environmentObject(myObject)修饰符将其传递给视图。

相关问题