0

I'm working on a project where I am supposed to compare two weathers, but I'm kind of stuck.

I'm entering the name of two cities which I'm appending to my array. Creating a for-loop to loop through the array and then sends then I'm passing the data to a function called downloadJsonData which are retrieving data from an API.

    @IBAction func compareTemperature(_ sender: Any) {
    if city1.text!.isEmpty || city2.text!.isEmpty{
        //Empty
        print("Empty")
    }
    else{
        cities.append(city1.text!)
        cities.append(city2.text!)

        for(index, _) in self.cities.enumerated(){
             self.downloadJsonData(path: self.cities[index]) {
                 print("Completed: Downloaded JSON data")
                 print(self.dataArray.count)
             }
         }
    }
}

So the for-loop is supposed to run twice, but the prints inside the completion blocks is only running once.

var dataArray:[ResponseData] = []
func downloadJsonData(path: String, completed: @escaping () -> ()){

        let mainUrl = "http://api.openweathermap.org/data/2.5/weather?q="
        let city = path
        let endUrl = "&appid=9e73e77789b74d085856e30d5dda6285&units=metric&lang=se"
        let urlString = mainUrl + city + endUrl

       guard let url = URL(string: urlString) else {return}

       URLSession.shared.dataTask(with: url) { (data, response, err) in
           guard let data = data else{
               return
           }

           do{
               self.dataArray.append(try JSONDecoder().decode(ResponseData.self, from: data))

               //Complete task in background
               DispatchQueue.main.async {
                   completed()
               }
           }
           catch let jsonErr{
               print(jsonErr)
           }
       }.resume()
   }

So when I'm trying to print the "self.dataArray.count" it always returns 1. I've tried for hours but cannot find a way to fix this issue.

Putte
  • 526
  • 1
  • 6
  • 15
  • Use a DispatchGroup. – matt Feb 20 '20 at 16:03
  • instead of my "DispatchQueue"? @matt – Putte Feb 20 '20 at 16:05
  • No you use both. – matt Feb 20 '20 at 16:05
  • That's possible, but that's pure practice. Instead rethink your design to asynchronous, cancelling, progress, etc. Blocking UI for waiting network response will result in non-user-friendly app. – Asperi Feb 20 '20 at 16:08
  • @matt So where should I add the wait method? – Putte Feb 20 '20 at 16:09
  • By the way, `for(index, _) in self.cities.enumerated(){ self.downloadJsonData(path: self.cities[index])` is silly. Just say `for city is self.cities {self.downloadJsonData(path:city)`. – matt Feb 20 '20 at 16:27
  • @matt Then the index won't be an integer, so I cannot get the index of the array – Putte Feb 20 '20 at 16:31
  • You won't need the index of the array because you are merely indexing right back into the same array, `self.cities`. But `for city in self.cities` hands you the elements one by one which is exactly what you are doing in this weird way. – matt Feb 20 '20 at 16:33

0 Answers0