0

I have a async function within functional tableview. I want to use the result of the function in my cell textlabel. But I don't know how to wait until the async function is finisched

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = self.tableView.dequeueReusableCell(withIdentifier: "groupDetail", for: indexPath)
    let group = trainingGroups[indexPath.row]
        cell.textLabel?.text = group.name
         self.getTrainerByID(trainerId: group.trainer_id_main, completion: { [self] (isRead, err,  trainer) in
            if isRead {
             cell.detailTextLabel?.text = trainer
                trainerMain = trainer!
             }else {
                 cell.detailTextLabel?.text = "Onbekend"
      cell.detailTextLabel?.text = group.trainer_id_main
      cell.layer.masksToBounds = true
      cell.layer.borderWidth = 0.25
      cell.layer.shadowOffset = CGSize(width: -1, height: 1)
      let borderColor: UIColor =  UIColor(red: 0, green: 45/255, blue: 114/255, alpha: 1)
      cell.layer.borderColor = borderColor.cgColor
      cell.accessoryType = .disclosureIndicator
      cell.tintColor = UIColor.white

      return cell

    }

 

How do I make te return of te cell wait until the getTrainerByID is finished?

Best regards,

Armand
Armand
  • 1
  • Should you really have an async call in the cell, wouldn't it be better to handle this for the whole table view (trainingGroups array) at once and then do reloadData() on the table view? – Joakim Danielson Jun 15 '21 at 14:35
  • Does this answer your question? [API async call in UITableView cellForRowAt](https://stackoverflow.com/questions/53102559/api-async-call-in-uitableview-cellforrowat) – EmilioPelaez Jun 15 '21 at 15:25

2 Answers2

1

You cannot "wait until the getTrainerByID is finished" to return the cell. cellForRow is synchronous so it requires the cell to be available at the time its execution completes.

My first question would be: Why does getTrainerByID have to be async? Is there a way to rework that method so that it is synchronous? If you're doing a lookup via an ID, is there a way to simply have the trainers stored in an Array or Dictionary (maybe this would require some pre-processing)?

If getTrainerByID absolutely must be async, then you can provide the cell with default placeholder text for the detailTextLabel to let the user know that the cell hasn't finished loading. It's difficult to say how to handle trainerMain without the full context of what you're trying to accomplish.

WongWray
  • 2,414
  • 1
  • 20
  • 25
0

It's unlikely you want to be making any async calls inside that method. As Joakim pointed out, what you ought to try and do is make a subsequent request off your initial data, only reloading the tableView when that has completed. For instance:

private func requestData() {
   networkService.getTrainingGroups { [weak self] groups in 
      self?.networkService.getTrainers(for: groups) { trainers in
          self?.tableViewData = GroupAndTrainers(groups, trainers) 
          self?.tableView.reloadData()
      }
   } 
}
Joe Williams
  • 113
  • 1
  • 7