使用Swift 4 Codable协议与未知的字典键

时间:2017-12-08 23:06:45

标签: swift swift4 codable

我正在与NASA的Near Earth Object Web Service合作,以检索要在应用程序中显示的数据。我理解如何使用Swift 4的Codable协议,但我不明白如何映射部分响应。

使用Paw,我检查了API的响应:

Image of API response data

如您所见,near_earth_objects结构是Dictionary,键是日期。问题是URL参数是日期,因此这些日期结构将根据请求的日期而更改。因此,我不知道在使用Codable协议时如何创建要自动映射的属性。

我试图在这些结构中获取的数据是包含Array s的Dictionary

Image of API response data

如果日期会随着请求日期的变化而变化,我怎样才能让我的模型对象符合Codable协议并映射这些结构?

2 个答案:

答案 0 :(得分:2)

如果您不介意在解码后保留Dictionary,则不需要知道Dictionary编译时的密钥。

您只需指定类型为Dictionary<String:YourCustomDecodableType>的属性即可。键将是与观察相对应的日期,值将是包含您自定义类型的所有对象的数组。

struct NearEarthObject: Codable {
    let referenceID:String
    let name:String
    let imageURL:URL

    private enum CodingKeys: String, CodingKey {
        case referenceID = "neo_reference_id"
        case name
        case imageURL = "nasa_jpl_url"
    }
}

struct NEOApiResponse: Codable {
    let nearEarthObjects: [String:[NearEarthObject]]

    private enum CodingKeys: String,CodingKey {
        case nearEarthObjects = "near_earth_objects"
    }
}

do {
    let decodedResponse = try JSONDecoder().decode(NEOApiResponse.self, from: data)
} catch {
    print(error)
}

答案 1 :(得分:0)

正如你所说,near_earth_objects是一个字典,但键不是日期,键是字符串,值是已知结构的数组。所以上面的代码将起作用:

...
let nearEarthObjects: [String: [IndexObject]]
...

enum CodingKey: String, CodingKeys {
    case nearEarthObjects = "near_earth_objects"
}

struct IndexObject: Decodable {
    ...
    let name: String
    ...
}