1

I am making an app where this block of code runs:

extension LikeOrDislikeViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        let uid = Auth.auth().currentUser?.uid
        var numRows = 0

        Database.database().reference().child("Num Liked").child(uid!).observeSingleEvent(of: .value, with: { (snapshot) in
            if let dictionary = snapshot.value as? [String: AnyObject] {
                let numMoviesLiked = ((dictionary["Number of Movies Liked"] as? Int))!

                if numMoviesLiked % 4 == 0 {
                numRows = numMoviesLiked/4
                }
            }
        })
        return numRows
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        cell.backgroundColor = UIColor.red
        tableView.rowHeight = 113
        cell.textLabel?.text = "\(indexPath.row)"

        return cell
    }
}

I need the "Database.database..." code to run before the return line. How can I do this?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Bob Samuels
  • 385
  • 2
  • 6
  • 16
  • 3
    This is a bad setup because `numberOfRowsInSection` will be called many times. Load your data once, not over and over. – rmaddy Oct 18 '18 at 21:33
  • The completion handler for `observeSingleEvent` runs **after** your `return numRows`. Place a few logging statements and you can easily see that in the output. You will have to place all the code that needs the data in the completion handler, or pass in your own custom completion handler and call that. See https://stackoverflow.com/questions/42464237/make-code-with-firebase-asynchronous/42464431#42464431, https://stackoverflow.com/questions/46863823/adding-data-and-querying-from-swift-to-firebase/46864260#46864260 – Frank van Puffelen Oct 19 '18 at 00:46

1 Answers1

-1

Database operations are heavy and take time a bit to complete. You should update your table view after Database.database... operation completed.

class LikeOrDislikeViewController {
    ...

    lazy var numRows: Int = {
        let uid = Auth.auth().currentUser?.uid
        Database.database().reference().child("Num Liked").child(uid!).observeSingleEvent(of: .value, with: { (snapshot) in
            if let dictionary = snapshot.value as? [String: AnyObject] {
                let numMoviesLiked = ((dictionary["Number of Movies Liked"] as? Int))!

                if numMoviesLiked % 4 == 0 {
                    self.numRows = numMoviesLiked/4
                    self.tableView.reloadData()
                }
            }
        })
        return 0
    }()
}

extension LikeOrDislikeViewController: UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return numRows
    }

    ...
}
Mojtaba Hosseini
  • 95,414
  • 31
  • 268
  • 278