如何在 Swift 中支持 array(array,string) 的变量 JSON 字段?
How do I support a variable JSON field of array(array,string) in Swift?
所有。
我正在尝试创建一个结构来保存具有特定结构的 API 调用的内容,但不确定如何编写它。
这是 API 的一个结果,我在为接收结构编码时遇到问题:
"10E": {
"baseSetSize": 264,
"block": "Guilds of Ravnica",
"boosterV3": [
[
"rare",
"mythic rare"
],
"uncommon",
"uncommon",
"uncommon",
"common",
"common",
"common",
"common",
"common",
"common",
"common",
"common",
"common",
"common",
"land",
"marketing"
],
"cards": [ ... ]
}
API 将 'boosterV3' 键列为格式 array(array, string)
。但是,一些返回的数据包含一个包含 16 个字符串的数组,并且至少有一个包含一个字符串数组作为它的第一个元素。
我试过使用以下结构:
struct MtGSet : Codable {
let name: String
let baseSetSize: Int
let block: String
let boosterV3: [String]
let cards: [MtGCard]
}
但是 运行 反对 API 产生这个错误:
[CodingKeys(stringValue: "boosterV3", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)],
debugDescription: "Expected to decode String but found an array instead.", underlyingError: nil))
是否可以在 Swift 中编写一个数据结构,以接受 16 个字符串值或 15 个字符串值和 1 个字符串数组作为 boosterV3
键?
谢谢。
像下面这样尝试。我没有测试我刚刚通过将 JSON 转换为 Swift 创建的。你也可以自己做,这里是https://app.quicktype.io/.
struct MtGSet : Codable {
let name: String
let baseSetSize: Int
let block: String
let boosterV3: [BoosterV3] // user [] of BoosterV3 instead of string
let cards: [MtGCard]
}
enum BoosterV3: Codable {
case string(String)
case stringArray([String])
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let x = try? container.decode([String].self) {
self = .stringArray(x)
return
}
if let x = try? container.decode(String.self) {
self = .string(x)
return
}
throw DecodingError.typeMismatch(BoosterV3.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for BoosterV3"))
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .string(let x):
try container.encode(x)
case .stringArray(let x):
try container.encode(x)
}
}
}
所有。
我正在尝试创建一个结构来保存具有特定结构的 API 调用的内容,但不确定如何编写它。
这是 API 的一个结果,我在为接收结构编码时遇到问题:
"10E": {
"baseSetSize": 264,
"block": "Guilds of Ravnica",
"boosterV3": [
[
"rare",
"mythic rare"
],
"uncommon",
"uncommon",
"uncommon",
"common",
"common",
"common",
"common",
"common",
"common",
"common",
"common",
"common",
"common",
"land",
"marketing"
],
"cards": [ ... ]
}
API 将 'boosterV3' 键列为格式 array(array, string)
。但是,一些返回的数据包含一个包含 16 个字符串的数组,并且至少有一个包含一个字符串数组作为它的第一个元素。
我试过使用以下结构:
struct MtGSet : Codable {
let name: String
let baseSetSize: Int
let block: String
let boosterV3: [String]
let cards: [MtGCard]
}
但是 运行 反对 API 产生这个错误:
[CodingKeys(stringValue: "boosterV3", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)],
debugDescription: "Expected to decode String but found an array instead.", underlyingError: nil))
是否可以在 Swift 中编写一个数据结构,以接受 16 个字符串值或 15 个字符串值和 1 个字符串数组作为 boosterV3
键?
谢谢。
像下面这样尝试。我没有测试我刚刚通过将 JSON 转换为 Swift 创建的。你也可以自己做,这里是https://app.quicktype.io/.
struct MtGSet : Codable {
let name: String
let baseSetSize: Int
let block: String
let boosterV3: [BoosterV3] // user [] of BoosterV3 instead of string
let cards: [MtGCard]
}
enum BoosterV3: Codable {
case string(String)
case stringArray([String])
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let x = try? container.decode([String].self) {
self = .stringArray(x)
return
}
if let x = try? container.decode(String.self) {
self = .string(x)
return
}
throw DecodingError.typeMismatch(BoosterV3.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for BoosterV3"))
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .string(let x):
try container.encode(x)
case .stringArray(let x):
try container.encode(x)
}
}
}