Извлечь элемент из таблицы Amazon DynamoDB, а затем передать ему значение NumberOfItemsInSection (Swift 4)?

Я пытаюсь получить элемент из таблицы (TheUserIds2018) Amazon DynamoDB, и я хотел бы передать элемент в качестве numberOfItemsInSection UICollectionViewCell, вот таблица, которую 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()


        })

}

вот номер элемента InSection:

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

Но при сборке и запуске приложения collectionViewCell не отображается на экране, оно пустое:

Я знаю, что причина в том, что collectionViewCell запускается раньше, чем viewWillAppear. Поэтому я попробовал следующий способ, но иногда он падает (с ошибкой: 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 есть две разные таблицы: TheUserIds2018 и Recommended. Вот как выглядит рекомендуемая статья:

Любой другой способ получить элемент из таблицы (TheUserIds2018), а затем передать его в число NumberOfItemsInSection?

Обновление: после добавления self.collectionView?.reloadDate() в основном потоке, он работает хорошо в большинстве случаев, но иногда падает, если попытаться прокрутить вниз сразу после запуска приложения, особенно при плохом интернет-соединении. Та же ошибка: Thread 1: Fatal error: Index out of range, Есть ли способ это исправить?

Окончательное обновление: наконец-то, с помощью @Rohi, теперь все работает. Я обновил коды на сегодняшний день.

1 ответ

Решение

Вызовите reloadData() после того, как вы назначите self.counters в главном потоке, он будет работать. Не раньше, чем назначать self.counters.

Другие вопросы по тегам