我尝试使用它构造结构和解码,但它仅在所有数据类型都与定义相同时才有效
例如,下面的代码工作正常:
{"key1": "stringValue", "key2": intValue, "key3": ["stringData1", "stringData2", "stringData3"]}
struct User: Decodable
{
var key1: String
var key2: Int
var key3: [String]
}
let decoder = JSONDecoder()
let decodedJsonData = try decoder.decode(User.self, from: data)
print(decodedJsonData)
如果 key3 包含不同的数据类型,我应该怎么做解码?
{"key1": "stringValue", "key2": intValue, "key3": ["stringData1", IntData, FloatData]}
使用具有关联值的枚举:
struct User: Codable {
let command, updated: Int
let data: [Datum]
}
enum Datum: Codable {
case double(Double)
case string(String)
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let x = try? container.decode(Double.self) {
self = .double(x)
return
}
if let x = try? container.decode(String.self) {
self = .string(x)
return
}
throw DecodingError.typeMismatch(Datum.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for Datum"))
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .double(let x):
try container.encode(x)
case .string(let x):
try container.encode(x)
}
}
}
要获取data
中的各个值,请使用如下代码:
let json = """
{"command": 1, "updated": 2, "data": ["stringData1", 42, 43]}
""".data(using: .utf8)
do {
let user = try JSONDecoder().decode(User.self, from: json!)
for d in user.data {
switch d {
case .string(let str): print("String value: (str)")
case .double(let dbl): print("Double value: (dbl)")
}
}
} catch {
print(error)
}