0

I was following this tutorial (https://www.youtube.com/watch?v=QMR6N6Vs_x0&feature=emb_err_woyt) and used the code for an Apple Watch Application. So everything works almost fine.

The strange thing is that not all the cities that I'm typing are accepted. It gives the error (see code) "incorrect user input!". But when I copy and paste the url that is generated and not correct due the code, it will work in de browser. It will accept that input. But my app won't.

I have searched but could not find anything similar. I think it is a very small thing to fix.

import Foundation

final class NetService: ObservableObject {

@Published var weather: WeatherData?
@Published var city = ""

let baseURL = URL(string: "https://api.openweathermap.org/data/2.5/weather")!
var query = ["q": "", "appid": "", "units": "metric"]

func loadWeatherInfo(by city: String) {

    guard baseURL.withQueries(query) != nil, city != "" else { print("URL isn't correct!"); return}

    query["appid"] = "HERE I PUT MY OWN API-KEY"
    query["q"] = city

    URLSession.shared.dataTask(with: baseURL.withQueries(query)!) { data, _, error in
        print(self.baseURL.withQueries(self.query)!)
        guard let data = data else { print(#line, #function, "\(error!.localizedDescription)"); return }

        if let weatherInfo = try? JSONDecoder().decode(WeatherData.self, from: data) {
            DispatchQueue.main.async { [weak self] in
                self?.weather = weatherInfo
            }
        } else {
            print(#line, #function, "incorrect user input!"); return
        }
    }.resume()
}
}

So my question is, why won't my code accept all the cities. I get the error on "Zeist", "Woerden", "Gent" and many more. If I copy the "build url" (https://api.openweathermap.org/data/2.5/weather?q=Zeist&appid=HERE I PUT MY OWN API-KEY&units=metric) from the console I get a return when i paste this in Safari. So the city is recognised.

{"coord":{"lon":5.23,"lat":52.09},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"base":"stations","main":{"temp":11.84,"feels_like":10.18,"temp_min":11.11,"temp_max":12.78,"pressure":1020,"humidity":58},"wind":{"speed":0.45,"deg":264,"gust":2.68},"clouds":{"all":7},"dt":1589534449,"sys":{"type":3,"id":2005313,"country":"NL","sunrise":1589514260,"sunset":1589570804},"timezone":7200,"id":2743977,"name":"Zeist","cod":200}

So the url is build correctly.

Thank for reading, I hope there is a solution.

Asperi
  • 228,894
  • 20
  • 464
  • 690
Moi
  • 43
  • 8
  • 2
    Please show your `WeatherData` object because it looks like it's the JSON parsing that's the issue here, not the user input. – Eric Aya May 15 '20 at 11:37
  • 1
    As @EricAya said, your model is failing to be parsed. Likely you have a non-optional property that the returned data is not populating. Look at the API responses for those cities and see if any of the fields are empty, if they aren't guaranteed to be populated then you should make the properties in your model optional. – clawesome May 15 '20 at 13:46

1 Answers1

0

Thanks to the comments above this post I have found the solution. In my WeatherData visibility is something that I collect from OpenWeatherMap. Not all cities have "visibility" as an output, so I have made this an optional and it works now!

Moi
  • 43
  • 8