JSONDecoder извлечь данные из строки в строке? - PullRequest
1 голос
/ 03 апреля 2020

XCODE 11.4 SWIFT 5.0

Я использую API для получения строки из JSON. Это мой результат API:

{
  "altimeter": {
    "repr": "3022",
    "spoken": "three zero point two two",
    "value": 30.22
  },
  "clouds": [
    {
      "altitude": 250,
      "modifier": null,
      "repr": "FEW250",
      "type": "FEW"
    }
  ],
  "dewpoint": {
    "repr": "25",
    "spoken": "two five",
    "value": 25
  },
  "flight_rules": "VFR",
  "meta": {
    "timestamp": "Tue, 04 Sep 2018 01:01:47 GMT"
  },
  "other": [],
  "raw": "KJFK 040051Z 20007KT 10SM FEW250 26/25 A3022 RMK AO2 SLP231 T02560250",
  "remarks": "RMK AO2 SLP231 T02560250",
  "remarks_info": {
    "dewpoint_decimal": {
      "repr": "25.0",
      "spoken": "two five point zero",
      "value": 25
    },
    "temperature_decimal": {
      "repr": "25.6",
      "spoken": "two five point six",
      "value": 25.6
    }
  },
  "runway_visibility": [],
  "sanitized": "KJFK 040051Z 20007KT 10SM FEW250 26/25 A3022 RMK AO2 SLP231 T02560250",
  "station": "KJFK",
  "temperature": {
    "repr": "26",
    "spoken": "two six",
    "value": 26
  },
  "time": {
    "dt": "Tue, 04 Sep 2018 00:51:00 GMT",
    "repr": "040051Z"
  },
  "units": {
    "altimeter": "inHg",
    "altitude": "ft",
    "temperature": "C",
    "visibility": "sm",
    "wind_speed": "kt"
  },
  "visibility": {
    "repr": "10",
    "spoken": "one zero",
    "value": 10
  },
  "wind_direction": {
    "repr": "200",
    "spoken": "two zero zero",
    "value": 200
  },
  "wind_gust": null,
  "wind_speed": {
    "repr": "07",
    "spoken": "seven",
    "value": 7
  },
  "wind_variable_direction": []
}

Я могу извлечь одностроковую информацию, такую ​​как «raw» и «station», но изо всех сил пытаюсь извлечь информацию из информации. Например, "Time" -> "retr"

struct AeroWX: Decodable {
    var raw: String
    var station: String
}



//button

            let url = URL(string: "https://avwx.rest/api/metar/\(ICAOdep)")!
            var request = URLRequest(url: url)
            request.addValue("xxxxxxxx", forHTTPHeaderField: "Authorization")

            let task = URLSession.shared.dataTask(with: request) { data, response, error in if response != nil
            {
                if let data = data, let body = String(data: data, encoding: .utf8)
                {
                    if body.contains("error")
                    {
                        print(body)
                        self.GlobalTimeStamp = "Invalid ICAO Code"
                        self.doLabelChangeError()
                    }
                    else
                    {
                       let user = try! JSONDecoder().decode(AeroWX.self, from: data); DispatchQueue.main.async
                       {
                            print(user.station)
                            print(user.raw)
                       //     print(user.retr)
                            self.GlobalMetar = user.raw
                            self.doLabelChange()
                        }
                    }
                 }
             }
             else
             {
                 print(error ?? "Unknown error")
             }

           }
           task.resume()
        }
        else
        {
            self.GlobalTimeStamp = "Invalid ICAO Code"
            self.doLabelChangeError()
        }

Кто-нибудь может помочь, чтобы извлечь время, retr также, а не только отдельные строки?

1 Ответ

1 голос
/ 03 апреля 2020

Вам нужна вложенная структура. Попробуйте это:

struct AeroWX: Decodable {

    struct Time: Decodable {
        let dt: Date
        let repr: String
    }

    var raw: String
    var station: String
    var time: Time
}

Вам также понадобится специальный форматер даты для стратегии декодирования даты декодера. Для декодирования вам нужно будет сделать следующее:

let formatter = DateFormatter()
formatter.dateFormat = "E, dd MMM yyyy HH:mm:ss 'GMT'"
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(formatter)
let aero = try decoder.decode(AeroWX.self, from: json)

Последнее, что я должен упомянуть, это то, что фактическое сокращение аббревиатуры часового пояса в поле даты в пакете json довольно необычно. Вам следует поговорить с вашим веб-разработчиком и выяснить, какие значения вы можете ожидать, кроме «GMT». Этот форматер даты всегда будет ожидать GMT.

...