如何在SwiftUI中使用ObservableObject加载数据?

时间:2019-11-29 03:14:50

标签: amazon-dynamodb swiftui combine

我正在尝试将依赖于基本DynamoDB资源的应用程序从UIKit过渡到SwiftUI,但是在将视图添加到列表时强制刷新视图时遇到了障碍。我已经在这组代码上工作了几个小时,尝试各种不同的事情,并且我想我可能会看看是否有人知道为什么“ SessionsData”似乎被扔掉了并且不会累积“ Sessions”对象。

有人有任何快速的想法吗?

class SessionsData: ObservableObject {

    let didChange = PassthroughSubject<SessionsData, Never>()
    @Published var data: [Sessions] = [] {
        didSet {
            didChange.send(self)
        }
    }

    init() {
        load()
    }

    func load() {
        let dynamoDBObjectMapper = AWSDynamoDBObjectMapper.default()
        let scanExpression = AWSDynamoDBScanExpression()
        scanExpression.limit = 20

        var temp : [Sessions] = []

        dynamoDBObjectMapper.scan(Sessions.self, expression: scanExpression).continueWith(block: { (task:AWSTask<AWSDynamoDBPaginatedOutput>!) -> Any? in
            if let error = task.error as NSError? {
                 print("The request failed. Error: \(error)")
             } else if let paginatedOutput = task.result {
                for session in paginatedOutput.items as! [Sessions] {
                    print("Item Found")
                    temp.append(session)
                }
                DispatchQueue.main.async {
                    self.data = temp
                    self.didChange.send(self)
                }
             }
            print(self.data.count)
            return true
         })
    }
}
struct Events: View {

    @ObservedObject var sessionsData = SessionsData()


    var body: some View {...}
}

2 个答案:

答案 0 :(得分:0)

我没有使用DynamoDB的经验,但是从SwiftUI / Combine的角度来看,这里有几件事。在ObseravbleObject中,有很大的变化,现在用objectWillChange声明,然后在newValue中发送willSet

class SessionsData: ObservableObject {

    public let objectWillChange = PassthroughSubject<[Sessions], Never>()

    public private(set) var items: [Sessions] = [] {
        willSet {
            objectWillChange.send(newValue)
        }
    }

    init() {
        self.items = []
    }

    public func load() {
        let dynamoDBObjectMapper = AWSDynamoDBObjectMapper.default()
        let scanExpression = AWSDynamoDBScanExpression()
        scanExpression.limit = 20

        var temp: [Sessions] = []

        dynamoDBObjectMapper
            .scan(Sessions.self,
                  expression: scanExpression)
            .continueWith(block: { (task:AWSTask<AWSDynamoDBPaginatedOutput>!) -> Any? in
                if let error = task.error as NSError? {
                   print("The request failed. Error: \(error)")
                } else if let paginatedOutput = task.result,
                    let sessions = paginatedOutput.items as? [Sessions] {
                    temp.append(contentsOf: sessions)
                }
                DispatchQueue.main.async {
                    self.items = temp
                }
            }
            return true
         })
    }
}

对于UI部分,您只需要调用上面.onApear()中定义的load()方法,其他所有事情都应该神奇地发生:

struct事件:查看{

@ObservedObject var sessionsData: SessionsData

var body: some View {
    List {
        ForEach(self.sessionsData.items) { session in
            Text(session.name) // or something of that kind
        }
    }   .onAppear(perform: { self.sessionsData.load() })
}

}

答案 1 :(得分:0)

看起来您过于复杂了代码。 x是不必要的。每当您更改push_back属性时,它都应该触发更新。

h