You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS应用使用AWS Amplify DataStore无法与DynamoDB后端同步

iOS Amplify DataStore无法同步至AppSync/DynamoDB排查

我开发的iOS应用采用AWS Cognito完成用户认证,功能正常;同时通过AWS Amplify的DataStore存储数据,使用Swift Package Manager引入amplify-ios包,版本范围设置为1.0.0 < 2.0.0。目前数据仅能保存至本地DataStore,无法同步至AppSync及后端DynamoDB——AWS控制台中对应的DynamoDB表已存在但始终为空。我已多次排查网络连接、重新搭建项目,均未解决问题。请问:

  1. 我哪里操作有误?
  2. 该Amplify库是否兼容AppSync?若不兼容,应使用何种替代方案?

相关代码

ToDoStore.swift

import Foundation
import Combine
import SwiftUI
import Amplify

class ToDoStore: ObservableObject {

    @Published private(set) var todos: [Todo] = []

    init() {
        self.getAllTodosFromDataStore()
    }


    func getAllTodosFromDataStore() {

        Amplify.DataStore.query(Todo.self) { (result) in
            switch result {
            case .success(let todos):
                DispatchQueue.main.async {
                    print("Got \(todos.count) Todos from DataStore initially")
                    self.todos = todos
                }
            case .failure(let error):
                print("Error getting Todos from DataStore: \(error.localizedDescription)")
            }
        }
    }


    func deleteTodoFromDataStore(for indexSet: IndexSet) {

        let todosToDelete = indexSet.map { self.todos[$0] }

        self.todos.remove(atOffsets: indexSet)

        for todo in todosToDelete {

            Amplify.DataStore.delete(todo) { (result) in
                switch result {
                case .success():
                    print("Deleted Todo from DataStore")
                case .failure(let error):
                    print("Error deleting Todo From DataStore: \(error)")
                }
            }
        }
    }


    private func addTodoToArray(_ todo: Todo) {

        if !self.todos.contains(todo) {
            self.todos.append(todo)
        }
    }

    private func deleteTodoFromArray(_ todo: Todo) {

        if let index = self.todos.firstIndex(of: todo) {
            self.todos.remove(at: index)
        }
    }

    private func updateTodoInArray(_ todo: Todo) {
        print("update?")
    }
}

AWSDataStoreApp.swift

import SwiftUI
import Amplify
import AWSCognitoAuthPlugin
import AWSDataStorePlugin
import Foundation


@main
struct AWSDataStoreTestApp: App {
    @ObservedObject var sessionManager = SessionManager()

    init() {
        configureAmplify()
        sessionManager.getCurrentAuthUser()

    }

    var body: some Scene {
        WindowGroup {
            switch sessionManager.authState {
            case .login:
                LoginView()
                    .environmentObject(sessionManager)
            case .resetPassword:
                ResetPasswordView()
                    .environmentObject(sessionManager)
            case .signUp:
                SignUpView()
                    .environmentObject(sessionManager)
            case .confirmCode(let username):
                ConfirmationView(username: username)
                    .environmentObject(sessionManager)
            case .session(let user):
                SessionView(user: user)
                    .environmentObject(sessionManager)

            }
        }
    }

    private func configureAmplify() {
        do {
            try Amplify.add(plugin: AWSCognitoAuthPlugin())
            try Amplify.add(plugin: AWSDataStorePlugin(modelRegistration: AmplifyModels()))

            try Amplify.configure()
            print("Amplify configured sucessfully")
        } catch {
            print("Could not intstall Amplify", error)
        }
    }
}

SessionView.swift

import SwiftUI
import Amplify
import CoreLocation

struct SessionView: View {
    @EnvironmentObject var sessionManager: SessionManager
    @ObservedObject var todoStore = ToDoStore()
    
    let user: AuthUser
    
    var body: some View {
        TodoListView()
            .onAppear(perform: {
                todoStore.getAllTodosFromDataStore()
            })
            .environmentObject(sessionManager)

    }
}


struct TodoListView: View {
    @EnvironmentObject var sessionManager: SessionManager

    @State private var todos: [Todo] = []
    
    var body: some View {
        NavigationView {
            VStack {
                List(todos) { todo in
                    Text(todo.name)
                }
                .onAppear {
                    // Query the DynamoDB table for Todo items
                    Amplify.DataStore.query(Todo.self) { result in
                        switch result {
                        case .success(let todos):
                            // Update the todos state with the retrieved Todo items
                            self.todos = todos
                        case .failure(let error):
                            print("Error retrieving Todo items: \(error)")
                        }
                    }
                }
                NavigationLink(destination: AddTodoView()
                    .environmentObject(sessionManager),
                               label: {
                        Text("Add todo")
                            .padding()
                            .foregroundColor(.white)
                            .background(Color.green)
                            .cornerRadius(10)
                            .font(
                                .system(size: 20))
                    })
            }
        }
    }
}

struct AddTodoView: View {
    @EnvironmentObject var sessionManager: SessionManager
    @State var name = ""
    var body: some View {
        VStack {
            TextField("Name", text: $name)
            Button(action: {
                // create todo
                let todo = Todo(name: name, ownerId: sessionManager.getUser().userId)
                Amplify.DataStore.save(todo) { result in
                    switch result {
                    case .success(let success):
                        // Update the todos state with the retrieved Todo items
                        print(success)
                        print("Saved")
                    case .failure(let error):
                        print("Error retrieving Todo items: \(error)")
                    }
                }
            }, label: {
                Text("Submit")
            })
        }
    }
}

额外信息

应用表现

应用能正常显示DataStore中添加的内容,但无法同步。Cognito认证功能正常,资源已正确添加至项目。

Amplify状态

% amplify status
    Current Environment: dev
┌──────────┬──────────────────────────────────┬───────────┬───────────────────┐
│ Category │ Resource name                    │ Operation │ Provider plugin   │
├──────────┼──────────────────────────────────┼───────────┼───────────────────┤
│ Auth     │ awsdatastoretest058f3478058f3478 │ No Change │ awscloudformation │
├──────────┼──────────────────────────────────┼───────────┼───────────────────┤
│ Api      │ awsdatastoretest                 │ No Change │ awscloudformation │

环境信息

  • 依赖管理:Swift Package Manager
  • Swift版本:Apple Swift 5.7
  • Amplify CLI版本:10.5.2
  • Xcode版本:14.0.1

我已重新创建项目、从头安装Amplify,排查过网络连接,均无效果。


排查与解决方案

1. Amplify库与AppSync兼容性确认

amplify-ios 1.x版本完全兼容AppSync,DataStore正是基于AppSync实现云端同步的,所以兼容性没问题,无需更换方案。

2. 核心排查点及修复建议

(1)启用DataStore云端同步

DataStore默认处于仅本地模式,你的代码未开启云端同步。修改configureAmplify方法:

private func configureAmplify() {
    do {
        let dataStorePlugin = AWSDataStorePlugin(modelRegistration: AmplifyModels())
        try Amplify.add(plugin: AWSCognitoAuthPlugin())
        try Amplify.add(plugin: dataStorePlugin)
        try Amplify.configure()
        // 启动云端同步
        try Amplify.DataStore.start()
        print("Amplify configured successfully")
    } catch {
        print("Could not install Amplify", error)
    }
}

(2)检查模型的同步与权限规则

确保Todo模型定义包含正确的@auth规则,关联认证用户:

type Todo @model @auth(rules: [{ allow: owner, ownerField: "ownerId" }]) {
  id: ID!
  name: String!
  ownerId: String!
}

如果缺少该规则,DataStore会因权限不足无法同步到云端。

(3)验证用户认证状态与令牌有效性

DataStore同步需要有效用户令牌,可在同步前打印状态排查:

Amplify.Auth.fetchAuthSession { result in
    switch result {
    case .success(let session):
        print("用户已登录: \(session.isSignedIn)")
        print("令牌有效: \(session.userPoolTokens != nil)")
    case .failure(let error):
        print("认证会话错误: \(error)")
    }
}

(4)检查AppSync配置与数据源

  • 确认amplifyconfiguration.json已正确添加到项目,文件需包含AppSync端点、认证信息。
  • 登录AWS控制台,检查AppSync API的数据源是否指向目标DynamoDB表,Resolver规则配置正确。

(5)启用详细日志排查

开启日志查看同步失败的具体原因:

// 在Amplify.configure()之前添加
Amplify.Logging.logLevel = .verbose

控制台中搜索DataStore、SyncEngine相关日志,定位错误根源。

(6)清空本地DataStore重试

若本地存在脏数据导致同步卡住,可清空本地存储后重新测试:

Amplify.DataStore.clear { result in
    switch result {
    case .success:
        print("DataStore已清空")
    case .failure(let error):
        print("清空DataStore失败: \(error)")
    }
}

内容的提问来源于stack exchange,提问作者Philip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 23:25:17