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

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

Вот мой код:

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";
    };
}

Я рекомендую вам использовать Decodable и Codable, чтобы у вас не было так много вложенных операторов if else. Вот пример от Apple: developer.apple.com/documentation/foundation/…

Keyhan Kamangar 22.01.2019 20:33
Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
0
1
104
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ошибки в вашем коде заключаются в том, что 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.

Это была крайне полезная информация! Большое спасибо за ответ!

cortlin dunlevy 24.01.2019 15:46

Другие вопросы по теме