SwiftUI中Amplify初始化报错,如何修复?(未使用Apollo SDK)
错误信息
Failed to initialize Amplify with ConfigurationError: AWSS3StoragePlugin.AWSS3StoragePlugin cannot be added after
Amplify.configure().
Recovery suggestion: Do not add plugins after callingAmplify.configure()./Users/ufukkosker/Library/Developer/Xcode/DerivedData/ArtApp-xxxxxxxhzyxxxxx/SourcePackages/checkouts/amplify-swift/Amplify/Categories/DataStore/DataStoreCategory.swift:21: Fatal error: DataStore category is not configured. Call Amplify.configure() before using any methods on the category.
问题根源
- 缺少DataStore插件:代码仅添加了AWSS3StoragePlugin,但使用DataStore功能必须配套添加AWSDataStorePlugin并注册模型。
- 提前调用DataStore方法:LaunchView的
onAppear中立即执行fetchArttist(),此时Amplify可能还未完成配置。 - 潜在重复配置风险:若项目其他位置存在
Amplify.configure()调用,会导致插件添加时机冲突。
解决方案
1. 完善Amplify初始化流程,添加DataStore插件
确保所有插件在Amplify.configure()之前添加,并注册Amplify CLI生成的模型:
import SwiftUI import UIKit import Amplify import AWSS3StoragePlugin import AWSDataStorePlugin // 定义Amplify配置完成通知 extension Notification.Name { static let amplifyConfigured = Notification.Name("AmplifyConfigured") } class AppDelegate: NSObject, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { do { // 依次添加所需插件 try Amplify.add(plugin: AWSS3StoragePlugin()) // 注册Amplify CLI生成的模型文件 try Amplify.add(plugin: AWSDataStorePlugin(modelRegistration: AmplifyModels())) try Amplify.configure() print("Amplify 配置完成:已加载Storage和DataStore插件") // 发送配置完成通知 NotificationCenter.default.post(name: .amplifyConfigured, object: nil) } catch { print("Amplify初始化失败:\(error)") } return true } } @main struct ArtApp: App { @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate var body: some Scene { WindowGroup { ContentView() } } }
2. 确保DataStore方法在Amplify配置完成后调用
修改AmplifyDataStoreConfig增加配置校验,同时在LaunchView中通过监听通知触发DataStore操作:
修改AmplifyDataStoreConfig
import Amplify import AWSDataStorePlugin final class AmplifyDataStoreConfig { static var shared = AmplifyDataStoreConfig() private init() {} // 校验Amplify是否完成配置 private func isAmplifyReady() -> Bool { return Amplify.isConfigured } func fetchArtist() async { guard isAmplifyReady() else { print("错误:Amplify尚未完成配置,无法调用DataStore方法") return } do { let items = try await Amplify.DataStore.query(Artist.self) items.forEach { artist in print("艺术家ID:\(artist.id)") } } catch let error as DataStoreError { print("查询艺术家失败:\(error)") } catch { print("未知错误:\(error)") } } }
修改LaunchView
struct LaunchView: View { @State var isAnimating: Bool = false @State var isPresent: Bool = false var body: some View { HStack(spacing: 0) { ZStack(alignment: .trailing) { Rectangle() .foregroundColor(.artOrangeLight) .frame(width: 128, height: 128) .offset(y: isAnimating ? .zero : -UIScreen.main.bounds.height) .animation(.spring().delay(0.5), value: isAnimating) Text("art") .foregroundColor(.artieLogoText) .font(.custom(.gothamLight, size: 90)) .offset(y: isAnimating ? .zero : -UIScreen.main.bounds.height) .animation(.spring().delay(1), value: isAnimating) } Text("ie") .foregroundColor(.artLogoText) .font(.custom(.gothamLight, size: 90)) .offset(x: isAnimating ? .zero : UIScreen.main.bounds.width) .animation(.spring().delay(1.5), value: isAnimating) } .onAppear{ isAnimating = true DispatchQueue.main.asyncAfter(deadline: .now() + 2) { isPresent = true } // 监听Amplify配置完成通知,再执行DataStore查询 NotificationCenter.default.addObserver(forName: .amplifyConfigured, object: nil, queue: .main) { _ in Task { await AmplifyDataStoreConfig.shared.fetchArtist() } } } .fullScreenCover(isPresented: $isPresent) { OnboardingView() } } }
3. 无Apollo SDK的GraphQL使用说明
Amplify DataStore内置GraphQL支持,只要你通过Amplify CLI创建了GraphQL API并生成了对应的AmplifyModels模型文件,就可以直接通过Amplify.DataStore的query/save等方法与GraphQL API交互,无需额外引入Apollo SDK。
内容的提问来源于stack exchange,提问作者Ufuk Köşker

