1

I would like to compare the results of two separate server calls and am struggling with how to do this using the closure format.

For example, if a weather api will return the temperature for one city at a time and I want to compare the temperatures in two cities, I'm struggling with how to wait for both calls to complete.

The code I am using, adapted from a single server call, can wait for the first result. However, I can't figure out how to then wait for the second result.

Here is my code:

func compareWeather (onecity:String, anothercity:String,completion:@escaping (_ response:String)->()){
    let city1:String = "Boston"
    let city2:Strng = "Palo Alto"
    self.getWeatherForCity(city: city1){//open 2
                answer in
    let temp1:String = answer
    }
    self.getWeatherForCity(city: city2){//open 2
                answer in
    let temp2:String = answer
    }

    //THIS DOES NOT WORK Since it is called before we here back from APIS BUT THIS IS WHAT I WANT TO accomplish

    completion("the temperature in Boston is ",temp1, "but the temperature in Palo Alto is ",temp2)
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
user1904273
  • 4,562
  • 11
  • 45
  • 96
  • I really hope there's a better alternative than the ones employing GCD and so forth listed in the linked to question. – user1904273 Oct 12 '18 at 05:20
  • Using `DispatchGroup` is the proper solution. – rmaddy Oct 12 '18 at 05:21
  • @user1904273 You can set a `var callsCompletedCount = 0`, increment same in each block. Set temp1 and temp2 in two different variables. And call your completion block if `callCompletedCount == 2` in both the block (`getWeatherForCity `) – Satish Oct 12 '18 at 06:22
  • @Satish Please don't do that. It has threading issues. Use `DispatchQueue`. – rmaddy Oct 12 '18 at 14:41
  • Thanks @rmaddy. I am not against `DispatchGroup`. But just want to understand how what I have mentioned would have threading issues. Will you be able to help me with this? – Satish Oct 13 '18 at 06:32
  • I actually ended up just putting the second call inside the completion block of the first call. Only upon completino of the first call, do we do the second one and upon completion of the second one, the combined phrase is formulated. I am curious if anyone sees any problems with this. It seems like a good way to use the closure pattern in Swift without having to use the dispatch or semaphore and assorted other methods. – user1904273 Oct 13 '18 at 16:44
  • @Satish It's not something that can be covered in the comments. And I meant `DispatchGroup`, not `DispatchQueue` in my earlier reply to you. – rmaddy Oct 13 '18 at 17:12
  • 1
    @user1904273 Your solution is valid. Though it is potentially slower. Using `DispatchGroup` allows the two async calls to the weather service to run concurrently. – rmaddy Oct 13 '18 at 17:15

0 Answers0