When I request data from api.weather.gov I get the following JSON (extract, only up to the first period or hour:
{
"@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,
I have been able to map it to a JSON Structure for the most part, with the exception of the first element:
"@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#"
}
],
This looks to me like a Swift Dictionary [String: [VersionStruct]], but in JSON looks like an Array with the first element a String and the second element a Struct of Strings, how do I represent this as a Swift Struct, I am confused, thank you
If the @context
property always contains a list of two elements with the first being a string and the second being representable by a given type, you can use a tuple:
struct GeoJSON {
let context: (String, Context)
...
struct Context {
let version, wx, geo, unit, vocab: String
}
}
Tuples are not Decodable
so you need to provide a custom Decodable
implementation:
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"
}
}
}