访问未安装在视图上的 StateObject 对象。这将每次创建一个新实例 - SwiftUI

Art*_*uro 54 swift swiftui

每次应用程序启动时我都必须进行一些初始设置,但我收到错误:

在此输入图像描述

错误很明显,答案却不是。我尝试将 init 放入子视图中,但我不能,它需要位于 root 中@main。我是这样定义的:

@StateObject private var amplifyConfig: AmplifyConfig = AmplifyConfig()

init() {
    if(amplifyConfig.isAmplifyConfigured == false) {
        amplifyConfig.dataStoreHubEventSubscriber()
        amplifyConfig.configureAmplify()
    }
}
Run Code Online (Sandbox Code Playgroud)

我如何摆脱该警告并实际实现它,这样它就不会创建多个实例,这就是我使用 @EnvironmentObject 的原因?

use*_*ser 51

在初始化之前您无法访问任何值,请使用onAppear()

import SwiftUI

@main
struct YourApp: App {
    
    @StateObject private var amplifyConfig: AmplifyConfig = AmplifyConfig()
    
    var body: some Scene {
        
        WindowGroup {
            ContentView()
                .onAppear() {
                    if (!amplifyConfig.isAmplifyConfigured) {
                        amplifyConfig.dataStoreHubEventSubscriber()
                        amplifyConfig.configureAmplify()
                    }
                }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:实际用例

import SwiftUI

@main
struct YourApp: App {
    
    @StateObject private var amplifyConfig: AmplifyConfig = AmplifyConfig()
    
    @State private var isLoaded: Bool = Bool()
    
    var body: some Scene {
        
        WindowGroup {
            
            VStack {
                if (isLoaded) { ContentView() }
                else { Text("Loading . . .") }
            }
            .onAppear() {
                if (!amplifyConfig.isAmplifyConfigured) {
                    amplifyConfig.dataStoreHubEventSubscriber()
                    amplifyConfig.configureAmplify()
                    completionHandler { value in isLoaded = value }   
                }
                else {
                    isLoaded = true  
                }
            }
        }   
    }
}


func completionHandler(value: @escaping (Bool) -> Void) {
    
    // Some heavy work here, I am using DispatchQueue.main.asyncAfter for replicating that heavy work is happening! But you use your own code here.
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + DispatchTimeInterval.milliseconds(3000)) { value(true) }

}
Run Code Online (Sandbox Code Playgroud)


MrA*_*zaa 5

我遇到了这个线程,接受的答案不适用于我的用例,尽管它是正确的。我使用以下解决方案修复了它。

AmplifyConfig您也可以自己在 init 中初始化,然后将其分配给@StateObject var ...。就像下面这样:

@StateObject private var amplifyConfig: AmplifyConfig

init() {
    let amplifyConfig = AmplifyConfig()
    self._amplifyConfig = StateObject(wrappedValue: amplifyConfig)

    if !amplifyConfig.isAmplifyConfigured {
        amplifyConfig.dataStoreHubEventSubscriber()
        amplifyConfig.configureAmplify()
    }
}
Run Code Online (Sandbox Code Playgroud)