提问人:GianlucaA 提问时间:2/8/2023 更新时间:2/8/2023 访问量:153
SwiftUI:如何在 App 启动前初始化 @StateObject 变量?
SwiftUI: how do I initialize a @StateObject variable before the app launches?
问:
基本上,在我的应用程序的 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)
}
}
}
有什么办法可以解决这个问题吗?
我尝试 await 函数初始化 UserProfileService 中的数据,但似乎没有任何效果。
答:
这
@main
struct myApp: App {
是应用程序的入口点。在此之前,任何事情都不应该或不会运行。因此,您需要更改您的要求,并在加载数据时显示一些进度/加载屏幕:
if userProfileService.isLoading {
ProgressView {
Text("Please wait...")
}
} else if !userProfileService.hasData() {
// ... same as before
虽然您可以在 中设置为 ,并在收到 Firabase 的响应时将其设置回 false。userProfileService.isLoading
true
init
UserProfileService
这当然是最原始的方式,只是为了显示状态。许多其他方法也是可能的,但关键是:如果你依赖于某些网络操作,请在应用中有一个状态,在该操作完成时“娱乐”用户。
@StateObject
用于需要引用类型的情况,以及这两种情况,用于需要与屏幕上某些内容的生存期相关的视图数据的真实来源。即在出现时创建,在消失时销毁。由于您不希望您的服务被破坏,因此它不是这项工作的正确工具。@State
@StateObject
其他一些选项是使用单例,请参阅选中核心数据的 Xcode 模板。或者,您可以使用@UIApplicationDelegateAdaptor
,该为您提供了一个位置,您可以创建服务并响应通常的应用生命周期委托事件。PersistenceController.shared
评论