Reputation: 217
I have this case where I get data from Firebase, put it in array, and populate it in my Table View
.
But the Table View
loads the data before the function finishes to append data into the array.
Therefore, I always get Index out of range
error.
If you guys have any other solution to my case, feel free to correct my code.
But for now, I only can think a way on how to make the function append the data into the array before Table View
load it.
Hopefully you guys get what I mean.
Here's the code:
import UIKit
import FirebaseFirestore
var arrayCurrentProduct = [currentProduct]()
var arrayRetrievedData: [String:Any] = [:]
var arrayConvertedPrice: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
}
func initProduct(selectedProduct: String) {
arrayCurrentProduct = referProduct(productName: selectedProduct)
}
private func referProduct(productName: String) -> [currentProduct] {
switch productName {
case Product.Microsoft.rawValue:
getPrices(document: "Msft") { (_) in
self.convertPrice(Type: "std")
self.convertPrice(Type: "dc")
self.tableView.reloadData()
self.dismiss(animated: true, completion: nil)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
default:
break
}
return arrayCurrentProduct
}
private func getPrices(document: String, completion: @escaping (_ String:Any?) -> Void) {
retrievePrice(document: document) { [weak self] (data) in
guard let self = self else {return}
self.arrayRetrievedData = data
completion(self.arrayRetrievedData)
}
}
private func convertPrice(Type: String) {
formatterCode(formatter: formatter)
var priceFormatted = ""
guard let price = arrayRetrievedData[Type] else {return}
if let formattedPrice = formatter.string(from: price as! NSNumber) {
priceFormatted = formattedPrice
}
arrayConvertedPrice.append(priceFormatted)
}
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellShowing = tableView.dequeueReusableCell(withIdentifier: ShowingTVCell.cellIdentifier, for: indexPath) as! ShowingTVCell
let cellInput = tableView.dequeueReusableCell(withIdentifier: InputTVCell.cellIdentifier, for: indexPath) as! InputTVCell
switch indexPath.section {
case 0:
cellShowing.labelName.text = microsoft[indexPath.row]
cellShowing.labelPrice.text = arrayConvertedPrice[indexPath.row] // Error index out of range
return cellShowing
case 1:
cellInput.labelSpec.text = microsoft[indexPath.row]
return cellInput
default:
return cellShowing
}
}
Here's a bit of the flow:
I select a product, initProduct()
called --> referProduct()
called --> get price from Firebase --> convert price to currency, append to array --> loaded by Table View
I've also tried to put reloadData()
in some places but it didn't work.
Any help will be appreciated.
Thankyou in advance.
Upvotes: 0
Views: 207
Reputation: 100
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
You wrote a magic number (4) before the fetching data. tableView try to create a 4 row per section with no data. You should update your numbersOfRowsInSection return value after fetching data.
Upvotes: 2