如何在Firebase完成用户数据下载后重新加载UITableView数据?

所以我有firebase的问题,因为它是异步的,我不知道如何正确使用它。 我的应用程序有待售产品,我从firebase数据库和firebase存储(图片)获得。 问题是我不知道何时或如何重新加载我的UITableView以获取所有数据而不会出现nil错误。 而且它更复杂,因为首先我需要从firebase获取我的salePost信息,之后我才能获得同样在tableview单元格中的用户信息。

这就是我获得salesPosts的方式

func getSalePosts() -> [SalePost]{ var salePosts = [SalePost]() FIR_DATABASE_SALE_POSTS.queryLimitedToFirst(NUMBER_OF_LOADED_POSTS).observeEventType(.Value, withBlock: { (snapshot) in for snap in snapshot.children{ let imgString = snap.value["image"] as! String! let imgNSURL = NSURL(string: imgString) let imgNSDATA = NSData(contentsOfURL: imgNSURL!) let downloadedImg = UIImage(data: imgNSDATA!) let newSalePost = SalePost(title: snap.value["title"] as! String!, userUID: snap.value["authorUID"] as! String!, postBody: snap.value["body"] as! String!, amountAvailable: snap.value["amountAvailable"] as! String!, unit: snap.value["unit"] as! String!, price: snap.value["price"] as! String!, image: downloadedImg!) salePosts.append(newSalePost) print("num of posts \(salePosts.count)") } }) { (error) in print(error.localizedDescription) } return salePosts } 

这是获取UserInfo的func(我将从salePost对象获取“userUID”)

  func getProducer(userUID:String) -> Producer{ var newProducer:Producer? FIR_DATABASE_USERS.child(userUID).observeEventType(.Value, withBlock: { (snap) in print(snap.description) let imgString = snap.value!["profilePic"] as! String! let imgNSURL = NSURL(string: imgString) let imgNSDATA = NSData(contentsOfURL: imgNSURL!) let downloadedImg = UIImage(data: imgNSDATA!) let someProducer = Producer( displayName: snap.value!["displayName"] as! String!, address: snap.value!["address"] as! String!, mobile: snap.value!["mobile"] as! String!, email: snap.value!["email"] as! String!, password: "", bio: snap.value!["bio"] as! String!, profilePic: downloadedImg!, openingHour: snap.value!["openingHour"] as! String!, closingHour: snap.value!["closingHour"] as! String!) newProducer = someProducer print(newProducer?.description) }) { (error) in print(error.localizedDescription) } return newProducer! } 

正如我所说,我不知道何时,何地以及如何调用这些函数(在我的Feed控制器中)使其“同步”并将所有数据都提供给tableview Cells。 我将感激你的每一个帮助。 我尝试谷歌,甚至在这里找到它,但没有任何帮助我。

创建所有salePosts您应该调用tableView.reloadData() 。 因此,在您循环创建将newSalePost附加到salePosts 。 由于这是一个异步调用,因此在函数结束时返回salePosts是没用的。

我假设你有一个viewController的属性tableView ,你将tableViewdelegatedatasource设置为viewController

不要忘记在主线程上调用tableView.reloadData()

例如: Dispatch.main.async { self.tableView.reloadData() }

对于将来看到此post的用户,您还可以使用Dispatch组来处理从Firebase获取数据的异步属性。 有关调度组工作的更多信息,您可以阅读Swift 3中的Dispatch Groups 。 Swift 4中的语法或多或少相同。 这就是我用tableview实现项目调度的方法。

 var anEmptyArray: [String] = [] var dbRef: DatabaseReference! @IBOutlet weak var myTable: UITableView! override func viewDidLoad() { super.viewDidLoad() retrieveDataFromDatabase() } func retrieveDataFromDatabase() { dbRef = Database.database().reference().child("user") dbRef.observe(.value, with: { snapshot in let group = DispatchGroup() let enumerator = snapshot.children while let rest = enumerator.nextObject() as? DataSnapshot { group.enter() self.categories.append(rest.value as! String) group.leave() } group.notify(queue: .main) { self.categoryTable.reloadData() } }) } 

我使用了snapshot.children,因为我的数据结构如何。 如何获取快照取决于您拥有的结构。 必须在dbRef.observe闭包内使用调度组。