Набор результатов JSON для OpenWeather API не возвращает значения для основного словаря в Swift - PullRequest
0 голосов
/ 22 января 2019

Я создаю приложение, которое извлекает информацию о погоде из API OpenWeather, используя JSON.Я вложил «IF» заявления, которые я использую, чтобы построить строку текущей погоды.Цель состоит в том, чтобы создать строку «Текущая погода (описание) с температурой (темп) и скоростью ветра (ветер)».К сожалению, оператор if для извлечения значения «temp» из словаря «main» не соответствует оператору else, который просто приводит к «Текущая погода (описание)».Может кто-нибудь сказать мне, если мой код делает что-то, что приведет к тому, что я не смогу присвоить значение "temp" из словаря "main" для

Вот мой код:

let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject

                        print(jsonResult)
                        if let description = ((jsonResult["weather"] as? NSArray)?[0] as? NSDictionary)?["description"] as? String {

                            print(description)
                            var weatherString = "Current weather is \(description)"
                            if let temp = ((jsonResult["main"] as? NSArray)?[0] as? NSDictionary)?["temp"] as? String {

                                weatherString += " with a temperature of \(temp)°"
                                if let wind = ((jsonResult["wind"] as? NSArray)?[0] as? NSDictionary)?["speed"] as? String {

                                    weatherString += " and a wind speed of \(wind)mph."

                                } else {

                                    weatherString += "."

                                }

                            } else {

                                weatherString += "."

                            }
                            DispatchQueue.main.sync(execute: {

                                self.weatherResult.text = weatherString

                            })

                        }

Вот результаты, которые я получаю от OpenWeather API:

{
    base = stations;
    clouds =     {
        all = 75;
    };
    cod = 200;
    coord =     {
        lat = "37.78";
        lon = "-122.42";
    };
    dt = 1548179880;
    id = 5391959;
    main =     {
        humidity = 60;
        pressure = 1030;
        temp = "51.37";
        "temp_max" = "55.04";
        "temp_min" = "46.04";
    };
    name = "San Francisco";
    sys =     {
        country = US;
        id = 5817;
        message = "0.0042";
        sunrise = 1548170423;
        sunset = 1548206575;
        type = 1;
    };
    visibility = 16093;
    weather =     (
                {
            description = "broken clouds";
            icon = 04d;
            id = 803;
            main = Clouds;
        }
    );
    wind =     {
        deg = 10;
        speed = "6.93";
    };
}

1 Ответ

0 голосов
/ 22 января 2019

Ошибки в вашем коде заключаются в том, что weather - это массив ([]), а main и wind - нет ({}). И speed и temp являются Double, а не String

Тем не менее JSONSerialization слишком сложен, Decodable проще, лучше читается и намного эффективнее.

API Openweathermap отправляет всегда согласованные данные.

struct WeatherData : Decodable {  
    let weather : [Weather]
    let main : Main
    let wind : Wind
}

struct Main : Decodable { let temp : Double }

struct Weather : Decodable { let description: String }

struct Wind : Decodable { let speed : Double }

...

do {
   let result = try JSONDecoder().decode(WeatherData.self, from: urlContent)
   let description = result.weather.first?.description ?? "unknown"
   let temp = result.main.temp
   let wind = result.wind.speed
   DispatchQueue.main.async {
       self.weatherResult.text = "Current weather is \(description) with a temperature of \(temp) and a wind speed of \(wind) mph."
   }

} catch { print(error) }

Примечания:

  • Не используйте NSDictionary / NSArray в Swift, используйте нативные типы.
  • Никогда не приводите результат от JSONSerialization к AnyObject, приведите его к ожидаемому типу (массив, словарь, строка или числовой тип).
  • Никогда не используйте .mutableContainers в Swift. Опция (как и .mutableLeaves) бессмысленна.
  • Никогда sync в основной поток. Всегда делай async.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...