从 Amazon DynamoDB 的 table 中检索一个项目,然后将其传递给 numberOfItemsInSection (Swift 4)?

Retrieve an item from a table of Amazon DynamoDB, then pass it to be the numberOfItemsInSection (Swift 4)?

我正在尝试从 Amazon DynamoDB 的 table (TheUserIds2018) 中检索一个项目,我想将该项目传递给 UICollectionViewCell 的 numberOfItemsInSection,这里是 table TheUserIds2018 看起来像:

代码如下:

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)

    let dynamoDbObjectMapper = AWSDynamoDBObjectMapper.default()
        dynamoDbObjectMapper.load(TheUserIds2018.self, hashKey: "TheUserIds2018", rangeKey: nil, completionHandler: { (objectModel: AWSDynamoDBObjectModel?, error: Error?) -> Void in
            if let error = error {
                print("Amazon DynamoDB Read Error: \(error)")
                return
            }


                if let count = objectModel?.dictionaryValue["_articleCounters"] {
                    self.counters = count as! Int
                } 
self.collectionView?.reloadData()


        })

}

这里是 numberOfItemsInSection:

 override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return self.counters
}

但是当我构建和 运行 应用程序时,屏幕上没有显示 collectionViewCell,它是空白的:

我知道原因是 collectionViewCell 在 vi​​ewWillAppear 之前启动。所以我尝试了下面的方法,但有时会崩溃(错误:Thread 1: Fatal error: Index out of range):

工作代码如下:

  override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(true)

    self.view.addSubview(activityView)
    activityView.hidesWhenStopped = true
    activityView.center = self.view.center
    activityView.startAnimating()

    let dynamoDbObjectMapper = AWSDynamoDBObjectMapper.default()
    dynamoDbObjectMapper.load(TheUserIds2018.self, hashKey: "TheUserIds2018", rangeKey: nil, completionHandler: { (objectModel: AWSDynamoDBObjectModel?, error: Error?) -> Void in
        if let error = error {
            print("Amazon DynamoDB Read Error: \(error)")
            return
        }

        DispatchQueue.main.async {
            if let count = objectModel?.dictionaryValue["_articleCounters"] {
                print("Count: \(count)")
                self.counters = count as! Int
                self.collectionView?.reloadData()
                if self.counters > 10 {
                    self.updateItems()
                } else {
                    self.getItems()
                }
              self.activityView.stopAnimating()
            }
        }
    })

}
func getItems() {
        let dynamoDbObjectMapper = AWSDynamoDBObjectMapper.default()
        var tasksList = Array<AWSTask<AnyObject>>()
        for i in 1...10 {
            tasksList.append(dynamoDbObjectMapper.load(RecommendArticles.self, hashKey: "userId" + String(11 - i), rangeKey: nil))
        }

        AWSTask<AnyObject>.init(forCompletionOfAllTasksWithResults: tasksList).continueWith { (task) -> Any? in
            if let cards = task.result as? [RecommendArticles] {
                    self.card = cards
                    print("cards counter: \(cards.count)")

            } else if let error = task.error {
                print(error.localizedDescription)
            }

            return nil

        }


    }

    func updateItems() {
        let dynamoDbObjectMapper = AWSDynamoDBObjectMapper.default()
        var tasksList = Array<AWSTask<AnyObject>>()
            for i in 1...self.counters {
                tasksList.append(dynamoDbObjectMapper.load(RecommendArticles.self, hashKey: "userId" + String(self.counters + 1 - i), rangeKey: nil))
            }
            AWSTask<AnyObject>.init(forCompletionOfAllTasksWithResults: tasksList).continueWith { (task) -> Any? in
                if let cards = task.result as? [RecommendArticles] {
                        self.card = cards
                        print("Real cards counter: \(cards.count)")

                } else if let error = task.error {
                    print(error.localizedDescription)
                }

                return nil

            }

    }

override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.counters

}



 override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: verticalCellId, for: indexPath) as! VerticalCellId

        if let link = self.card?[indexPath.item]._imageURL {
            let url = URL(string: link)
            cell.photoImageView.kf.setImage(with: url)

        }

    }

PS:我的 AWS DynamoDB 中有两个不同的 table:TheUserIds2018 和 RecommendArticles。 RecommendArticles 如下所示:

还有其他方法从 table (TheUserIds2018) 检索项目,然后将其传递给 numberOfItemsInSection 吗?

Update:在主线程添加self.collectionView?.reloadDate()后,在大多数情况下运行良好,但如果在应用程序启动后立即尝试向下滚动有时会崩溃,特别是在互联网连接不良时。同样的错误:Thread 1: Fatal error: Index out of range。有什么办法可以解决这个问题?

最终更新:终于,在@Rohi 的帮助下,它现在可以工作了。我已经更新了代码。

在主线程中分配给 self.counters 后调用 reloadData() 它将起作用。不在分配 self.counters.

之前