1

My database tree

enter image description here

Hello, I am trying to retrieve data to to tableview but although I can read data from firebase database, I cannot display them in table view. My code is below, I hope you can help me.

class Calls {

var callType: String?
var callHospital: String?

init(callType: String?, callHospital: String?) {
    self.callType = callType
    self.callHospital = callHospital
}
}

class myCallsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

var ref:DatabaseReference!
var myCallList = [Calls]()

@IBOutlet weak var callListTableView: UITableView!

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "customcell", for: indexPath) as! myCallsViewControllerTableViewCell

    let test = myCallList[indexPath.row]
    cell.callType?.text = test.callType
    cell.callHospital?.text = test.callHospital

    return cell
}

override func viewDidLoad() {
    super.viewDidLoad()

     callListTableView.dataSource = self
     callListTableView.delegate = self
   LoadCalls()
}

func LoadCalls() {
    ref = Database.database().reference()
    let userID = Auth.auth().currentUser?.uid
    ref.child("calls").queryOrdered(byChild: "userID").queryEqual(toValue: userID!).observe(.childAdded, with: { (snapshot) in
        if snapshot.childrenCount > 0{
        self.myCallList.removeAll()
            for result in snapshot.children.allObjects as! [DataSnapshot]{
                let results = result.value as? [String : AnyObject]
                let type = results?["calltype"]
                let hospital = results?["hospital"]
                let myCalls = Calls(callType: type as! String?, callHospital: hospital as! String?)
                self.myCallList.append(myCalls)
        }
                 self.callListTableView.reloadData()
        }
        })
}
KENdi
  • 7,576
  • 2
  • 16
  • 31
  • Can you please put a **print statement** inside the for loop of LoadCalls and show us the result – Siyavash Oct 03 '17 at 14:25
  • I put the dump statement like this: let myCalls = Calls(callType: type as! String?, callHospital: hospital as! String?) self.myCallList.append(myCalls) dump(myCalls) and the result is Kan_Bagisi_Portali.Calls #0 - callType: nil - callHospital: nil ▿ Kan_Bagisi_Portali.Calls #0 - callType: nil - callHospital: nil ▿ Kan_Bagisi_Portali.Calls #0 - callType: nil - callHospital: nil.... goes on like this – Semih Yildirim Oct 03 '17 at 15:47
  • I want to check to see if you are actually receiving any data from firebase as there doesn’t seem to be a problem with your code – Siyavash Oct 03 '17 at 16:41
  • ok but how will you check? – Semih Yildirim Oct 03 '17 at 17:59

2 Answers2

2

I solved the problem, thank you guys,Blake and Siyavash, so much. I registered the cell and put dispatch main queue and it worked. Here is the latest code: class Calls {

var callType: String?
var callHospital: String?

init(callType: String?, callHospital: String?) {
    self.callType = callType
    self.callHospital = callHospital
}

}

class myCallsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

var ref:DatabaseReference!
var myCallList = [Calls]()

@IBOutlet weak var callListTableView: UITableView!

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "customcell", for: indexPath) as! myCallsViewControllerTableViewCell

    let test = myCallList[indexPath.row]
    cell.callType?.text = test.callType
    cell.callHospital?.text = test.callHospital

    return cell
}

override func viewDidLoad() {
    super.viewDidLoad()

     callListTableView.dataSource = self
     callListTableView.delegate = self
   LoadCalls()
}

func LoadCalls() {
    ref = Database.database().reference()
    let userID = Auth.auth().currentUser?.uid
    ref.child("calls").queryOrdered(byChild: "userID").queryEqual(toValue: userID!).observe(.childAdded, with: { (snapshot) in
                let results = snapshot.value as? [String : AnyObject]
                let type = results?["calltype"]
                let hospital = results?["hospital"]
                let myCalls = Calls(callType: type as! String?, callHospital: hospital as! String?)
                self.myCallList.append(myCalls)
                DispatchQueue.main.async {
                    self.callListTableView.reloadData()
                }
        })
}
0

Your issue probably has to do with the fact that you're calling reloadData() from a closure, which means you're updating the UI from a background thread. Check out this answer:

Swift UITableView reloadData in a closure

Blake
  • 122
  • 1
  • 7
  • I tried but it gives me Assertion failure in -[UITableView _dequeueReusableCellWithIdentifier:forIndexPath:usingPresentationValues:] then crashes – Semih Yildirim Oct 03 '17 at 15:52
  • In the code you posted, you're not registering the cell with the tableview. Are you doing that elsewhere? https://stackoverflow.com/questions/12737860/assertion-failure-in-dequeuereusablecellwithidentifierforindexpath – Blake Oct 03 '17 at 16:22
  • yes I do in a UITableViewCell as @IBOutlet weak var callType: UILabel! IBOutlet weak var callHospital: UILabel! – Semih Yildirim Oct 03 '17 at 17:58
  • I think we may be speaking about two different things because the cell is not normally registered with the tableview in the UITableViewCell class. The registering happens in the tableview class. Check this out: https://www.hackingwithswift.com/example-code/uikit/how-to-register-a-cell-for-uitableviewcell-reuse – Blake Oct 03 '17 at 19:32