Когда я запрашиваю данные с api.weather.gov, я получаю следующий JSON (выдержка, только до первого периода или часа:
{
"@context": [
"https://geojson.org/geojson-ld/geojson-context.jsonld",
{
"@version": "1.1",
"wx": "https://api.weather.gov/ontology#",
"geo": "http://www.opengis.net/ont/geosparql#",
"unit": "http://codes.wmo.int/common/unit/",
"@vocab": "https://api.weather.gov/ontology#"
}
],
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-95.406033800000003,
39.349170399999998
],
[
-95.40841660000001,
39.326447799999997
],
[
-95.382835100000008,
39.324328799999996
],
[
-95.380447500000002,
39.347050999999997
],
[
-95.406033800000003,
39.349170399999998
]
]
]
},
"properties": {
"units": "us",
"forecastGenerator": "HourlyForecastGenerator",
"generatedAt": "2024-07-07T13:28:43+00:00",
"updateTime": "2024-07-07T10:55:15+00:00",
"validTimes": "2024-07-07T04:00:00+00:00/P7DT21H",
"elevation": {
"unitCode": "wmoUnit:m",
"value": 9.1440000000000001
},
"periods": [
{
"number": 1,
"name": "",
"startTime": "2024-07-07T09:00:00-04:00",
"endTime": "2024-07-07T10:00:00-04:00",
"isDaytime": true,
"temperature": 82,
"temperatureUnit": "F",
"temperatureTrend": "",
"probabilityOfPrecipitation": {
"unitCode": "wmoUnit:percent",
"value": 15
},
"dewpoint": {
"unitCode": "wmoUnit:degC",
"value": 26.111111111111111
},
"relativeHumidity": {
"unitCode": "wmoUnit:percent",
"value": 89
},
"windSpeed": "5 mph",
"windDirection": "ESE",
"icon": "/icons/land/day/tsra_hi,20?size=small",
"shortForecast": "Isolated Showers And Thunderstorms",
"detailedForecast": ""
},
{
"number": 2,
По большей части мне удалось сопоставить его со структурой JSON, за исключением первого элемента:
"@context": [
"https://geojson.org/geojson-ld/geojson-context.jsonld",
{
"@version": "1.1",
"wx": "https://api.weather.gov/ontology#",
"geo": "http://www.opengis.net/ont/geosparql#",
"unit": "http://codes.wmo.int/common/unit/",
"@vocab": "https://api.weather.gov/ontology#"
}
],
Мне это кажется словарем Swift [String: [VersionStruct]], но в JSON это выглядит как массив с первым элементом в виде строки и вторым элементом в виде структуры строк. Как мне представить это как структуру Swift? в замешательстве, спасибо
Попробуйте MKGeoJSONDecoder.
То, что вы получаете от NOAA, называется JSON-LD , JSON для связывания данных. Формально JSON-LD org . Для этого на github есть несколько библиотек Swift, например: github.com/kasei/swift-jsonld/tree/master
Если свойство @context
всегда содержит список из двух элементов, первый из которых является строкой, а второй может быть представлен заданным типом, вы можете использовать кортеж:
struct GeoJSON {
let context: (String, Context)
...
struct Context {
let version, wx, geo, unit, vocab: String
}
}
Кортежи не являются Decodable
, поэтому вам необходимо предоставить собственную Decodable
реализацию:
struct GeoJSON: Decodable {
let context: (String, Context)
enum CodingKeys: String, CodingKey {
case context = "@context"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
var nested = try container.nestedUnkeyedContainer(forKey: .context)
let string = try nested.decode(String.self)
let context = try nested.decode(GeoJSON.Context.self)
self.context = (string, context)
}
}
extension GeoJSON {
struct Context: Codable {
let version, wx, geo, unit, vocab: String
enum CodingKeys: String, CodingKey {
case wx, geo, unit, version = "@version", vocab = "@vocab"
}
}
}
Попробуйте app.quicktype.io. Вы увидите, что это не
[String:[VersionStruct]]
, это набор разных типов. API, скорее всего, предназначен для использования JavaScript с динамическим типом.