[英]TableView loaded before fetching data Firebase / Swift
我有一個 FireBase 數據庫,里面我有一個產品表和另一個帶有這些產品 ID 的訂單表,我想做的是根據訂單表中的 ID 從產品表中獲取產品,因為 FireBase 只會允許我一一獲取產品,在我獲取訂單表中引用的所有產品之前加載我的 tableview。
繼承人我是怎么做到的:
struct Product: Decodable, Encodable{
var id: String?
var ref: String
var description: String
var type: String
var price: String
var qtyOrdred:Int?
}
struct Order:Decodable, Encodable {
var id: String?
var isValide: Bool
var madeBy: String
var info: String?
var ordredProd: [OrderedProduct]
}
struct OrderedProduct:Decodable, Encodable {
var id: String
var qty: Int
}
func getData(completion: @escaping ([Product])->Void){
var allProduct = [Product]()
for product in orderedProduct {
getProductWithKey(qty: product.qty, key: product.id) { (p) in
print(p.ref)
allProduct.append(p)
}
}
}
func getProductWithKey(qty: Int,key: String, completion: @escaping (Product)->Void) {
Database.database().reference().child("products").child(key).observeSingleEvent(of: .value) { (snap) in
if let productObject = snap.value as? [String: Any]
{
if let ref = productObject["ref"],
let price = productObject["price"],
let type = productObject["type"],
let description = productObject["description"],
let id = productObject["id"]{
let p = Product(id: id as? String, ref: ref as! String, description: description as! String, type: type as! String, price: price as! String, qtyOrdred: qty)
completion(p)
}
}
}
}
我這樣稱呼它:
override func viewWillAppear(_ animated: Bool) {
self.getData { (ps) in
print(ps)
self.tableView.reloadData()
}
}
問題是它總是打印一個空數組,而我的 tableview 數據永遠不會改變
您沒有從getData
完成返回,您需要一個調度組
let g = DispatchGroup()
func getData(completion: @escaping ([Product])->Void){
var allProduct = [Product]()
for product in orderedProduct {
g.enter()
getProductWithKey(qty: product.qty, key: product.id) { (p) in
print(p.ref)
allProduct.append(p)
g.leave()
}
}
g.notify(queue:.main) {
completion(allProduct)
}
}
一旦 for 循環完成,您的 getData function 就會返回。 由於循環內的調用是異步的,因此循環結束時沒有任何數據。
無需重新加載表,只需在它們到達時插入行。
for product in orderedProduct {
getProductWithKey(qty: product.qty, key: product.id) { [weak self] (p) in
guard let self = self else { return }
allProduct.append(p)
guard let index = allProduct.firstIndex(of: p) else { return }
self.tableView.insertRow(at: IndexPath(row: index, section: 0))
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.