如何使用异步函数初始化应用程序?

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

我需要我的应用程序在启动时配置后端,这是执行此操作的函数:

// Initializes Amplify
final func configureAmplify() async {
    do {
//            Amplify.Logging.logLevel = .info
        let dataStore = AWSDataStorePlugin(modelRegistration: AmplifyModels())
        let syncWithCloud = AWSAPIPlugin()
        let userAuth = AWSCognitoAuthPlugin()

        try Amplify.add(plugin: userAuth)
        try Amplify.add(plugin: dataStore)
        try Amplify.add(plugin: syncWithCloud)
        try Amplify.configure()
        print("Amplify initialized")
    } catch {
        print("Failed to initialize Amplify with \(error)")
    }
}

我尝试将它放在 @main init 中,如下所示:

init() async {
    await networkController.configureAmplify()
}

但我收到以下错误:

类型“MyApplicationNameApp”不符合协议“App”

我尝试应用建议,然后初始化它:

init() {
        
}

但这看起来很奇怪,所以现在我有 2 个 init。这里发生了什么以及在应用程序启动时初始化多个异步函数的正确方法是什么,例如:

  1. 上面的代码(配置放大)
  2. 检查用户是否登录
  3. 设置会话

等等

注意:在上面的示例中永远不会调用

init() async
,这是这个问题中的另一个问题,那么应用程序启动时初始化异步函数的正确方法是什么。

swiftui swiftui-environment
2个回答
11
投票

使用

ViewModifier

.task{
    await networkController.configureAmplify()
}

您可以将

Task
添加到
init
,但可能会遇到问题,因为 SwiftUI 可以在必要时重新创建
View

init(){
    Task(priority: .medium){
        await networkController.configureAmplify()
    }
}

或者您可以使用

ObservableObject
,它是
@StateObject

使用

@StateObject
SwiftUI 只会为声明该对象的结构的每个实例创建一次该对象的新实例。

https://developer.apple.com/documentation/swiftui/stateobject

@main
struct YourApp: App {
    @StateObject var networkController: NetworkController = NetworkController()
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
class NetworkController: ObservableObject{
    
    init() {
        Task(priority: .medium){
            await configureAmplify()
        }
    }
    // Initializes Amplify
    final func configureAmplify() async {
        do {
            //            Amplify.Logging.logLevel = .info
            let dataStore = AWSDataStorePlugin(modelRegistration: AmplifyModels())
            let syncWithCloud = AWSAPIPlugin()
            let userAuth = AWSCognitoAuthPlugin()
            
            try Amplify.add(plugin: userAuth)
            try Amplify.add(plugin: dataStore)
            try Amplify.add(plugin: syncWithCloud)
            try Amplify.configure()
            print("Amplify initialized")
        } catch {
            print("Failed to initialize Amplify with \(error)")
        }
    }
}

0
投票

通常我们使用

.task
进行异步/等待,但这仅适用于视图(它在出现时开始并在消失时取消),因此不适合您在应用程序启动时运行任务的用例。 Scene
文档
建议使用
.onChange
作为启动任务的地方,这是他们进行后台处理的示例:

.onChange(of: locale) {
    Task.detached(priority: .background) {
        // ...
    }
}

因此,使用这个想法,要使任务在应用程序启动时运行一次,您可以尝试以下操作:

WindowGroup {
    ContentView()
}
.onChange(of: 0, initial: true) {
    Task {
        // async actions to perform once on app launch
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.