Извлечь элемент из таблицы 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.