firebase SwiftUI:如何在应用程序启动前初始化@StateObject变量?

t30tvxxf  于 2023-02-09  发布在  Swift
关注(0)|答案(2)|浏览(122)

基本上,我在应用的AppDelegate方法中连接到Firebase。然后,我需要在应用启动之前初始化我的UserProfileService。在UserProfileService init中,我连接到Firebase以获取经过验证的用户数据并存储它。
出现问题的原因是,如果我在应用启动之前不初始化UserProfileService,正如您在下面的代码中看到的,当我运行函数。hasData时()来检查UserProfileService中是否包含我需要的数据,它应该在phoneRegistrationView或mainTabBarView中结束。如果用户确实已经过身份验证,则在应用启动时,由于UserProfileService的初始化需要等待Firebase检索数据,因此函数. hasData()返回false并显示phoneRegistrationView()几毫秒,然后返回true并转到mainTabBarView。

@main
struct myApp: App {
    @StateObject private var userProfileService = UserProfileService()
    var body: some Scene {
        WindowGroup {
        // user not registered or authenticated
        if !userProfileService.hasData() {
            NavigationView {
                phoneRegistrationView()
            }
            .environmentObject(userProfileService)
        }
        // user registered and profile completed
        else {
            mainTabBarView()
            .environmentObject(userProfileService)
        }
    }
}

有什么办法可以解决这个问题吗?
我尝试使用wait函数初始化UserProfileService中的数据,但似乎没有任何效果。

lnlaulya

lnlaulya1#

@main
struct myApp: App {

是应用程序的入口点。在此之前不应该或不会运行任何内容。因此,您需要更改您的要求,并在加载数据时显示一些进度/加载屏幕:

if userProfileService.isLoading {
            ProgressView {
                Text("Please wait...")
            }
        } else if !userProfileService.hasData() {
        // ... same as before

虽然您可以在UserProfileServiceinit中将userProfileService.isLoading设置为true,并在从Firabase获得响应时将其设置回false。
这当然是最原始的方式,只是为了显示状态。还有很多其他的方式是可能的,但关键是:如果您依赖于某些网络操作,请在应用中设置一个状态,以便在操作完成时“娱乐”用户。

wecizke3

wecizke32#

@StateObject用于当你需要一个引用类型时,这两种情况都适用于当你需要一个与屏幕上某个东西的生命周期相关的视图数据的真实来源时。例如,在出现时创建,在消失时销毁。由于你不希望你的服务被销毁,@StateObject不是适合这项工作的工具。
还有一些选择是使用singleton,请参阅Xcode模板中的PersistenceController.shared,并检查核心数据。或者您可以使用@UIApplicationDelegateAdaptor,它为您提供了一个创建服务和响应常见应用生命周期委托事件的位置。

相关问题