json - 解码 JSON 键数组
问题描述
我有这个JSON
数据:
{
"cities": [
{
"id": 1,
"name": "Paris",
"country_code": "FR",
"attractions": [
"CityHall",
"Theatre",
"Port"
],
"population": 0
},
{
"id": 2,
"name": "Nice",
"country_code": "FR",
"attractions": [
"CityHall"
],
"population": 0
},
{
"id": 3,
"name": "Berlin",
"country_code": "DE",
"attractions": [
"Theatre",
"Port"
],
"population": 0
},
{
"id": 4,
"name": "Munich",
"country_code": "DE",
"attractions": [
"Theatre"
],
"population": 0
},
{
"id": 5,
"name": "Amsterdam",
"country_code": "NL",
"attractions": [
"Theatre",
"Port"
],
"population": 0
},
{
"id": 6,
"name": "Leiden",
"country_code": "NL",
"attractions": [
"CItyHall",
"Theatre"
],
"population": 0
}
]
}
我正在.request(.getCities).map([City].self, atKeyPath: "cities")
使用对象使用 Moya 对其进行解码:
struct City {
let id: Int
let name: String
let countryCode: String
//let attractions: [Attraction]
let population: Int
}
extension City: Decodable {
enum CodingKeys: String, CodingKey {
case id = "id"
case name = "name"
case countryCode = "countryCode"
//case attractions = "attractions"
case population = "population"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(Int.self, forKey: .id)
name = try container.decode(String.self, forKey: .name)
countryCode = try container.decode(String.self, forKey: .countryCode)
//attractions = try container.decode([Attraction].self, forKey: .attractions)
population = try container.decode(Int.self, forKey: .population)
}
}
简单而漂亮,但问题是我无法弄清楚如何将该attractions
数组放入此处。我有它enum
并试图通过使用来获取密钥codingPath
enum Attraction: String {
case CityHall
case Theatre
case Port
}
extension Attraction: Decodable {
enum CodingKeys: String, CodingKey {
// confusion mode initiated :) do I use it the same as in struct here?
case cityHall = "CityHall"
case theatre = "Theatre"
case port = "Port"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let attraction = container.codingPath.first!.stringValue // that would get the first key into string but how to deal with enum?
}
}
另外,如果解码得attractions
很好,City
对象会解码嵌套的对象/数组吗?
解决方案
简单漂亮
不,简单漂亮是
struct Root : Decodable {
let cities : [City]
}
struct City : Decodable {
let id: Int
let name: String
let countryCode: String
let atractions: [Attraction] // note the misspelling
let population: Int
}
enum Attraction: String, Decodable {
case cityHall = "CityHall", theatre = "Theatre", port = "Port"
}
let data = Data(jsonString.utf8)
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let result = try decoder.decode(Root.self, from: data)
print(result.cities)
} catch {
print(error)
}
推荐阅读
- ios - 将数据从模型传递到 SwiftUI 中的视图
- android - 是否可以将嵌套图的片段作为起始目的地?
- java - 此代码可以运行以向客户发送电子邮件和短信通知。需要进行一些更改,以确保如果对象中的电子邮件为空,则不会发送电子邮件
- c++ - 错误:“Name1”未在此范围内声明
- sql-server - 多个身份插入和日期列的 SQLAlchemy 问题
- android - 工具栏中的搜索选项作为第二行
- swift - 为什么在if语句之外使用return时在范围内找不到'newArray'
- php - 级联删除不适用于 php Laravel 8.21.0
- excel - 代码:用于 excel createSession 的 MS Graph API 的 itemNotFound 错误,我可以使用 sharedWithMe API 调用获取项目 ID
- sql - PostgreSQL 全部