Swift 可自行编码 JSON
Swift Codable on self-typed JSON
我正在尝试(至少)解码 JSON 看起来像这样的内容:
{
"type": "row",
"title": "Hello...",
"subtitle": "...from JSON"
}
然而,“类型”定义了它代表的 Codable 类型(例如,“行”到 Row
)。我见过很多例子,其中“type”是一个值,其余的嵌套在一个“payload”值中,如下所示:
{
"type": "row",
"payload:
{
"title": "Hello...",
"subtitle": "...from JSON"
}
}
但在我的场景中,它被压平了。我如何编写自定义解码器来读取类型,然后(重新?)使用该知识进行解码?
这是我在此处发布的答案的一个非常小的变体:
enum Item: Decodable {
case data1(Data1)
case data2(Data2)
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
// read type first
let type = try container.decode(String.self, forKey: .type)
// using type, continue decoding and save decoded data
switch type {
case "type1":
let data = try Data1(from: decoder)
self = .data1(data)
case "type2":
let data = try Data2(from: decoder)
self = .data2(data)
default:
throw DecodingError.unknownType
}
}
private enum CodingKeys: String, CodingKey {
case type
}
private enum DecodingError: String, Error {
case unknownType
}
}
struct Data1: Decodable {
}
struct Data2: Decodable {
}
我正在尝试(至少)解码 JSON 看起来像这样的内容:
{
"type": "row",
"title": "Hello...",
"subtitle": "...from JSON"
}
然而,“类型”定义了它代表的 Codable 类型(例如,“行”到 Row
)。我见过很多例子,其中“type”是一个值,其余的嵌套在一个“payload”值中,如下所示:
{
"type": "row",
"payload:
{
"title": "Hello...",
"subtitle": "...from JSON"
}
}
但在我的场景中,它被压平了。我如何编写自定义解码器来读取类型,然后(重新?)使用该知识进行解码?
这是我在此处发布的答案的一个非常小的变体:
enum Item: Decodable {
case data1(Data1)
case data2(Data2)
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
// read type first
let type = try container.decode(String.self, forKey: .type)
// using type, continue decoding and save decoded data
switch type {
case "type1":
let data = try Data1(from: decoder)
self = .data1(data)
case "type2":
let data = try Data2(from: decoder)
self = .data2(data)
default:
throw DecodingError.unknownType
}
}
private enum CodingKeys: String, CodingKey {
case type
}
private enum DecodingError: String, Error {
case unknownType
}
}
struct Data1: Decodable {
}
struct Data2: Decodable {
}