2016-09-14 104 views
0

所以我有一个与firebase的问题,因为它是异步的,我不知道如何正确使用。我的应用程序中有销售产品的Feed,我从Firebase数据库和Firebase存储获取(图片)。问题是我不知道什么时候或如何重新加载我的UITableView以获取所有数据而不会收到零错误。而且它更加复杂,因为首先我需要从firebase获取我的salePost信息,然后才能获得也位于tableview单元格中的用户信息。如何在Firebase完成用户数据下载后重新加载UITableView数据?

这是我如何得到我的salePosts

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 
} 

这是FUNC这是越来越的UserInfo(我会得到从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! 
} 

因此,正如我所说,我不知道何时,何地以及如何调用这些函数(在我的馈送控制器中)使其“同步”,并将所有数据都传送到tableview单元格。我会感谢每一个帮助。我尝试谷歌,甚至在这里找到它,但没有任何帮助我。

+0

你怎么cellforrowatindexpath方法看起来像? –

+2

您不能从包含异步任务的方法返回某些内容。使用完成处理程序。这里有几百个相关的问题。 – vadian

+0

@vadian谢谢你!完成处理程序为我工作! –

回答

1

一旦你创建了所有的salePosts,你应该打电话给tableView.reloadData()。因此,在您循环创建您的newSalePost到您的salePosts的附加位置之后。由于这是一个异步调用,在您的函数结束时返回您的salePosts是无用的。

我假设你有你的viewController的属性tableView并且您设置了tableViewdelegatedatasource是你viewController

不要忘记在主线程中调用tableView.reloadData()。例如:Dispatch.main.async { self.tableView.reloadData() }

0

对于将来的用户看到这篇文章,您还可以使用Dispatch组来处理从Firebase中检索数据的异步属性。有关调度组的更多信息,请参阅Dispatch Groups in Swift 3。 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关闭中使用。

相关问题