我正在尝试将一些表单值保存到Firestore,然后在表视图单元格中将这些值显示为IBOutlet变量。
到目前为止,这些值已成功保存到Firestore中,并且我有一个快照侦听器,该模型带有将这些Firestore值转换为本地数组的模型。但是,这些值不能追加到数组,并且我不断收到“索引0超出空数组的边界”错误。
奇怪的是,这套相同的代码集(更改了变量名)被用于另一项功能,并且效果很好。
我进行了print()检查,并确认数组为空。 IBOutlet也已正确连接,我尽力确保在表视图单元格填充值之前发生Firestore异步调用。
我仍然停留在“索引0超出空数组的边界”致命错误。我一定在这里遗漏了一些非常明显的东西。
// I declared the meds array storing "Med" as a model created to convert Firestore form values to a local array
var meds = [Med]()
override func viewDidLoad() {
super.viewDidLoad()
if meds.count > 0 {
print("Nice!")
} else {
print("Empty array")
}
// Creates empty view when no meds are added
tableView.backgroundView = emptyView
tableView.backgroundView?.isHidden = true
// Customize table view styles
self.tableView.separatorStyle = .singleLine
tableView.tableFooterView = UIView()
self.tableView?.backgroundColor = UIColor.white
// Listens to changes in meds data
medListener = ref.addSnapshotListener { querySnapshot, error in
guard let snapshot = querySnapshot else {
print("Error listening for channel updates: \(error?.localizedDescription ?? "No error")")
return
}
snapshot.documentChanges.forEach { change in
self.handleDocumentChange(change)
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
// Helper methods to update changes in table view cell with Firestore, and vice versa
func addMedToTable(_ med: Med) {
guard !meds.contains(med) else {
return
}
// Add new med to meds array
meds.append(med)
meds.sort()
guard let index = meds.firstIndex(of: med) else {
return
}
print(index)
// Adds new med into table view
tableView.insertRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
}
func updateMedInTable(_ med: Med) {
guard let index = meds.firstIndex(of: med) else {
return
}
meds[index] = med
tableView.reloadRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
}
func removeMedFromTable(_ med: Med) {
guard let index = meds.firstIndex(of: med) else {
return
}
meds[index] = med
tableView.deleteRows(at: [IndexPath(row: index, section: 0)], with: .automatic)
}
func handleDocumentChange(_ change: DocumentChange) {
guard let med = Med(document: change.document) else {
return
}
switch change.type {
case .added:
addMedToTable(med)
case .modified:
updateMedInTable(med)
case .removed:
removeMedFromTable(med)
@unknown default:
fatalError()
}
}