1

I am trying to create a weather App in Swift without using Podfiles and I have reached a stumbling block in terms of passing a dictionary as an argument in parsing JSON. The location function is as follows:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    let location = locations[locations.count - 1]
    if location.horizontalAccuracy > 0 {
        locationManager.startUpdatingLocation()
        locationManager.delegate = nil
        print("longitude = \(location.coordinate.longitude), latitude = \(location.coordinate.latitude)")

        let latitude = String(location.coordinate.latitude)
        let longitude = String(location.coordinate.longitude)
        let params : [String : String] = ["lat" : latitude, "lon" : longitude, "appid" : APP_ID]
        getWeatherData(url: WEATHER_URL, parameters: params)

    }
}

So to parse the JSON I have created the following function:

private func getWeatherData(url: String, parameters: [String : String]) {
    let JsonURLString:[String: Any] = ["url": WEATHER_URL, "parameters": parameters]
    print(JsonURLString)
    guard let url = URL(string: JsonURLString) else { return }
    URLSession.shared.dataTask(with: url) { ( data, response, err ) in
        DispatchQueue.main.sync {
            if let err = err {
                print("Failed to get data from url:", err)
                return
            }
            guard let data = data else { return }
            do {
                let decoder = JSONDecoder()
                decoder.keyDecodingStrategy = .convertFromSnakeCase
                let city = try decoder.decode(WeatherData.self, from: data)
                self.weatherData.city = city.name
            } catch {
                print(error)
                self.cityLabel.text = "Connection issues"
            }
        }
    }.resume()
}

The error I am having is the line Cannot convert the value of type '[String: Any]' to expected argument type 'String' in the line guard let url = URL(string: JsonURLString) else { return }. I am wondering if I have gone down a rabbit hole and maybe use an alternative approach. I wanted to use codable in Swift 4 as this is supposed to be an easier way of parsing JSON. Now in this example, I am not sure. Any help would be much appreciated.

5
  • 1
    You can't directly build a URL from a dictionary. Your issue has nothing to do with your JSON parsing code or using Codable. Your issue is creating a URL from a dictionary. Commented Apr 25, 2019 at 19:09
  • You should use URLComponents to build the URL from all of the pieces that you have. Commented Apr 25, 2019 at 19:14
  • Or should I rewrite this function and pass in the co-ordinates of "Lat" and "Long"? So for instance private func getWeatherData(Lat: Double, Long: Double) ? Commented Apr 25, 2019 at 19:15
  • I am not familiar with URLComponents any good resources? Commented Apr 25, 2019 at 19:43
  • The reference documentation and search. You'll find plenty of examples here. Commented Apr 25, 2019 at 20:05

1 Answer 1

1

Try this code.

JsonURLString is a [String: Any] type object not a String type. So you nee to convert it to a String type object.

private func getWeatherData(url: String, parameters: [String : String]) {
   let JsonURLString:[String: Any] = ["url": WEATHER_URL, "parameters": parameters]
   print(JsonURLString)
   let urlString = JsonURLString["url"] as? String
   guard let url = URL(string: urlString!) else { return }
   URLSession.shared.dataTask(with: url) { ( data, response, err ) in
   DispatchQueue.main.sync {
      if let err = err {
          print("Failed to get data from url:", err)
          return
      }
      guard let data = data else { return }
       do {
           let decoder = JSONDecoder()
           decoder.keyDecodingStrategy = .convertFromSnakeCase
           let city = try decoder.decode(WeatherData.self, from: data)
           self.weatherData.city = city.name
         } catch {
           print(error)
           self.cityLabel.text = "Connection issues"
         }
      }
   }.resume()
}
Sign up to request clarification or add additional context in comments.

1 Comment

Cheers Gregory will try this later.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.