我需要我的应用程序在启动时配置后端,这是执行此操作的函数:
// 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。这里发生了什么以及在应用程序启动时初始化多个异步函数的正确方法是什么,例如:
等等
注意:在上面的示例中永远不会调用
init() async
,这是这个问题中的另一个问题,那么应用程序启动时初始化异步函数的正确方法是什么。
使用
ViewModifier
.task{
await networkController.configureAmplify()
}
您可以将
Task
添加到 init
,但可能会遇到问题,因为 SwiftUI 可以在必要时重新创建 View
init(){
Task(priority: .medium){
await networkController.configureAmplify()
}
}
或者您可以使用
ObservableObject
,它是 @StateObject
使用
SwiftUI 只会为声明该对象的结构的每个实例创建一次该对象的新实例。@StateObject
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)")
}
}
}
通常我们使用
.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
}
}