当我从 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 结构,我很困惑,谢谢
如果
@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"
}
}
}