带有动态键的 Swift Codable
Posted
技术标签:
【中文标题】带有动态键的 Swift Codable【英文标题】:Swift Codable with dynamic keys 【发布时间】:2018-11-15 17:46:02 【问题描述】:我有 JSON 结构 为:
"periods":
"2018-06-07": [
"firstName": "Test1",
"lastName": "Test1"
],
"2018-06-06": [
"firstName": "Test1",
"lastName": "Test1"
]
我试着像这样解析它:
public struct Schedule: Codable
public let periods: Periods
public struct Periods: Codable
public let unknown: [Inner]
public struct Inner: Codable
public let firstName: String
public let lastName: String
private struct CustomCodingKeys: CodingKey
var stringValue: String
init?(stringValue: String)
self.stringValue = stringValue
var intValue: Int?
init?(intValue: Int)
return nil
public init(from decoder: Decoder) throws
let container = try decoder.container(keyedBy: CustomCodingKeys.self)
self.unknown = try container.decode([Inner].self, forKey: CustomCodingKeys(stringValue: "2018-06-06")
但我只能得到一个值(2018-06-06)
的结果。我在这里有多个要解析的日期。这可能吗?
【问题讨论】:
你可以手动解析 或者我使用app.quicktype.io快速生成我的结构体 【参考方案1】:好的,所以我是这样想的:
public struct Schedule: Codable
public let periods: Periods
public struct Periods: Codable
public var innerArray: [String: [Inner]]
public struct Inner: Codable
public let firstName: String
public let lastName: String
private struct CustomCodingKeys: CodingKey
var stringValue: String
init?(stringValue: String)
self.stringValue = stringValue
var intValue: Int?
init?(intValue: Int)
return nil
public init(from decoder: Decoder) throws
let container = try decoder.container(keyedBy: CustomCodingKeys.self)
self.innerArray = [String: [Inner]]()
for key in container.allKeys
let value = try container.decode([Inner].self, forKey: CustomCodingKeys(stringValue: key.stringValue)!)
self.innerArray[key.stringValue] = value
结果我得到了这样的字典:["2018-06-06": [Inner]]
其中键是这个日期字符串,值是 Inner。
【讨论】:
亲爱的 Masta 什么是 CustomCodingKeys? 我想维护字典插入顺序..如何实现? 如何获取所有 2018-06-06 密钥?【参考方案2】:我认为 JSON 应在开头附加 并在末尾附加
以便成为有效的 JSON,然后您可以使用以下代码轻松提取句点:
struct Period: Decodable
let firstName: String, lastName: String
let schedule = try? JSONDecoder().decode([String:[String:[Period]]].self, from: jsonData!)
let periods = schedule?.values.first?.values
【讨论】:
【参考方案3】:假设您省略了围绕此块的 和
并且这是有效 JSON 所必需的,以下是解析内容的最简单解决方案,您真的不需要处理
CodingKey
因为你的名字与 JSON 中的键匹配,所以合成的 CodingKey
可以正常工作:
public struct Schedule: Codable
public let periods : [String:[Inner]]
public struct Inner: Codable
public let firstName: String
public let lastName: String
let schedule = try? JSONDecoder().decode(Schedule.self, from: json)
print(schedule?.periods.keys)
print(schedule?.periods["2018-06-07"]?[0].lastName)
关键是外部 JSON 是一个 JSON 对象(字典/映射),具有单个键 periods
该键的值是另一个数组映射。像这样分解它,一切都会自动消失。
【讨论】:
以上是关于带有动态键的 Swift Codable的主要内容,如果未能解决你的问题,请参考以下文章
在 Swift 中编写一个带有排序键的漂亮打印 JSON 对象