-1

When an item is selected within my tableView, I want the first func, fetchChosenExerciseData, to be executed before the second, goToSegue, is triggered. How can I implement this? I have had a look at completion blocks but to no avail.

A snippet of my code is below:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let cell = tableView.cellForRow(at: indexPath) as! UITableViewCell
    exerciseChosen = cell.textLabel!.text!
    duplicatesRemovedFromSetDataList.removeAll()
    fetchChosenExerciseData()
    goToSegue()

Thanks in advance.

gcpreston
  • 135
  • 1
  • 12
  • And it will be. What's the issue? – mag_zbc Apr 30 '19 at 12:25
  • The functions are executed almost simultaneously, therefore the data has not be retrieved before the segue is triggered. – gcpreston Apr 30 '19 at 12:26
  • write the goToSegue() function inside the fetchChosenExerciseData(). if they are in same class. – Ben Rockey Apr 30 '19 at 12:27
  • Or as you suggested, use a completion block as parameter of your `fetchChosenData()` function – Y.Bonafons Apr 30 '19 at 12:29
  • They are not executed simultaneously. `fetchChosenExerciseData` will execute first, then `goToSegue`. Now whether you are scheduling some asynchronous task inside `fetchChosenExerciseData` is another matter. It would help if you posted the definition of `fetchChosenExerciseData` function – mag_zbc Apr 30 '19 at 12:30

4 Answers4

1

Since fetchChosenExerciseData is asynchronous you need this structure

func fetchChosenExerciseData(completion:@escaping()->()) {
    Api.load { 
        completion()
    }
}

Call

fetchChosenExerciseData { 
    goToSegue()
}
Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87
  • I now get an error within ** didSelectRowAt**, saying "missing argument for parameter 'completion'". Is this where I insert `fetchChosenExerciseData { goToSegue() }`? Apologies for the beginner questions – gcpreston Apr 30 '19 at 13:53
  • Code within **didSelectRowAt** has not changed but the function has. `func fetchChosenExerciseData(completion:@escaping()->()){ //code completion()` – gcpreston Apr 30 '19 at 14:01
0

this is simply achievable use a completion handler:

func fetchChosenExerciseData(_ completion: @escaping () -> Void) {
     // do what you need
     completion()
}

in your didSelectRowAt you can insert your second function

fetchChosenExerciseData {
    // goToSegue
}
Alastar
  • 1,284
  • 1
  • 8
  • 14
0

It seems your function fetchChosenExerciseDatahas some asynchoronous part or some code that is being executed on different Queue.

For conditions like this you should use completion block. So you would have to declare the `fetchChosenExerciseData' like this

func fetchChosenExerciseData (completion (()->()))
{
// Enter your code 
completion()
}

I have read you have done this solution, but i believe there must be some mistake in that

Talha Ahmad Khan
  • 3,416
  • 5
  • 23
  • 38
0

First of all add completion block to your method fetchChosenExerciseData like

func fetchChosenExerciseData(finished: () -> Void) {
     print("Doing something whatever you want!")
     finished()
}

and then call your function goToSegue from completion block of your first method like

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let cell = tableView.cellForRow(at: indexPath) as! UITableViewCell
    exerciseChosen = cell.textLabel!.text!
    duplicatesRemovedFromSetDataList.removeAll()
    fetchChosenExerciseData{
    goToSegue()
   }
}

Hope this help!