swift iOS应用程序使用AWS Amplify DataStore,但不与后端(DynamoDB)同步

egdjgwm8  于 2023-01-01  发布在  Swift
关注(0)|答案(1)|浏览(191)

我有一个应用程序,使用AWS Cognito来验证用户。验证工作得很好。该应用程序还使用AWS Amplify将项目保存到DataStore。我使用Swift Package Manager将Amplify安装为一个名为amplify-ios的包。当我添加包时,我指定了"最高到下一个主要版本",1. 0. 0〈2. 0. 0。
事实上,该应用程序不会将保存到DataStore的日期与AppSync同步。它只会将它们保存在本地。我三次检查了我的AWS控制台:数据的DynamoDB表存在,但它是空的。无论如何,没有保存任何数据!
我做错了什么?此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")
            })
        }
    }
}

应用程序显示添加到数据存储区的项目,一切正常,但不同步。资源似乎正确添加到项目中。通过Cognito的身份验证工作正常,但数据存储区同步不正常。

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

Dependency manager: Swift PM Swift version: Apple Swift version 5.7 (swiftlang-5.7.0.127.4 clang-1400.0.29.50) Target: arm64-apple-darwin21.6.0 Amplify CLI version: 10.5.2 Xcode version: 14.0.1 (14A400)
我做了一个新的项目。我从头开始安装放大器。我检查了类似的帖子,并确保我的应用程序连接到互联网(它是)。我尝试了一切。没有工作。

ykejflvf

ykejflvf1#

我在https://github.com/aws-amplify/amplify-swift/issues/2632中也描述了这个问题。
看来,我错过了添加一个单独的插件,这是必要的开始同步本地数据存储在手机和后台在AWS.因此,答案是添加到我的主应用程序swift文件如下:

try Amplify.add(plugin: AWSAPIPlugin())

因此,我从应用init()调用的整个函数如下所示:

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

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

相关问题