TableView загружается перед извлечением данных Firebase / Swift - PullRequest
0 голосов
/ 01 октября 2019

У меня есть база данных FireBase, внутри у меня есть таблица продуктов и другая таблица заказов с идентификаторами этих продуктов. Я пытаюсь получить продукты из таблицы продуктов на основе идентификаторов внутри таблицы заказов, посколькуFireBase позволит мне получать продукты по одному, мой просмотр таблицы загружается до того, как я получу все продукты, на которые есть ссылки в таблице заказов.

вот как я это сделал:

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()
        }
    }

Проблема в том, что он всегда печатает пустой массив, и мой просмотр таблицыданные никогда не меняются

Ответы [ 2 ]

2 голосов
/ 01 октября 2019

Вы не вернетесь после завершения 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)
     }
}
0 голосов
/ 01 октября 2019

Ваша функция getData возвращается, как только цикл for завершен. Поскольку вызов внутри цикла является асинхронным, по окончании цикла никаких данных нет.

Вместо перезагрузки таблицы просто вставляйте строки по мере их поступления.

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))
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...