Search code examples
iosswiftuitableviewparse-platformreload

Reloading Data in TableView after completing parse function


I am trying to reload the data after the function is completed:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    if let presentingVC = presentingViewController as? DealsViewController {

 //checks if presenting VC's city is the same as original, doesn't run if it is      
 if presentingVC.city != self.currentCity {
        DispatchQueue.main.async {
            //reloads the data but before completion of the below function "getDealInfo"
            presentingVC.DealsTableView.reloadData()
            presentingVC.DealsTableView.layoutIfNeeded()
        }
    }
//checks if presenting VC's city is the same as original, doesn't run if it is        
if presentingVC.city != self.currentCity {
        presentingVC.city = self.currentCity
        presentingVC.deleteAllDeals()
        //this is the function that gets called
        presentingVC.getDealInfo()
        presentingVC.cityOutlet.setTitle(self.currentCity,for: .normal)
        }
       
    }
    tableView.deselectRow(at: indexPath, animated: true)
    searching = false
    self.dismiss(animated: true, completion: nil)
    searchBar.resignFirstResponder()
}

As you can see, I call the reload function after returning to the previous view controller for new information that is supplied. However, the tableview updates prior to receiving the new values. As a result, my tableView is empty, however my values are stored in my arrays.

getDealInfo is Asynchronous:

    func getDealInfo() {
    let query = PFQuery(className: "Deal")
    query.whereKey("City", equalTo: city)
    query.order(byDescending: "Priority")
    query.findObjectsInBackground(block: { (objects: [PFObject]?,error: 
    Error?) in
    if let objects = objects {
        for object in objects {
            self.dealsArray.append(object["Deal"] as! String)
              }
            }
       }
    })
 }

Solution

  • Add a completion handler to getDealInfo in order to be notified when it finishes:

    func getDealInfo(_ completionHandler: @escaping () -> Void) {
        //Do async work
        completionHandler()
    }
    

    Then in the calling code:

    presentingVC.getDealInfo {
        self.presentingVC.DealsTableView.reloadData()
    }
    

    If the completion handler isn't being called in the main thread then you want to use DispatchQueue.main.async like you're currently doing so the call to reloadData is done in the main thread.