Swift 4.2 - 解码 JSON 相同密钥不同类型的地方
Swift 4.2 - Decode JSON Where Same Key Is Different Type
我正在使用以下模型解码对象
struct ACDeviceLastData {
var DA: ACDeviceLastDataBody = ACDeviceLastDataBody()
}
struct ACDeviceLastDataBody {
var amOn: Bool = false
var enabledZones: [Int] = []
var fanSpeed: Int = 0
var mode: Int = 0
var tempTarget: Float = 0.00
}
extension ACDeviceLastData: Decodable {
init(from decoder: Decoder) throws {
//Create Container
let container = try decoder.container(keyedBy: ACDeviceCodingKeys.self)
//Decode Data
DA = try container.decodeIfPresent(ACDeviceLastDataBody.self, forKey: .DA) ?? ACDeviceLastDataBody()
}
}
extension ACDeviceLastDataBody: Decodable {
init(from decoder: Decoder) throws {
//Create Container
let container = try decoder.container(keyedBy: ACDeviceCodingKeys.self)
//Decode Data
amOn = try container.decodeIfPresent(Bool.self, forKey: .amOn) ?? false
enabledZones = try container.decodeIfPresent([Int].self, forKey: .enabledZones) ?? []
fanSpeed = try container.decodeIfPresent(Int.self, forKey: .fanSpeed) ?? 0
mode = try container.decodeIfPresent(Int.self, forKey: .mode) ?? 0
tempTarget = try container.decodeIfPresent(Float.self, forKey: .tempTarget) ?? 0.00
}
}
问题在于 DA
的值并不总是相同的类型。它有时可以采用整数数组的格式,有时采用 ACDevieLastDataBody 的格式。我试过做一个 do-try-catch 但无法完全弄清楚如何让它工作(如果这是正确的做法)
我的问题是,当它是一个整数数组时,我将如何在解码器不抛出的情况下解码它们。非常感谢任何帮助。提前谢谢你。
您需要在 init(from decoder: Decoder)
中安排类型
这是一个简单的转换,注意类型可能不完全相同,因此兼容性由您安排,您的负担。
我看不到 JSON,但是 JSON 代码非常容易做到,因为 JSON 类型在原子级别总是很简单。
希望对您有所帮助...
今天过得愉快!
首先,您必须选择一种存储数据的方式。为简单起见,我们将 Int
的数组存储为单独的 属性:
struct ACDeviceLastData {
var DA: ACDeviceLastDataBody = ACDeviceLastDataBody()
var DAasInts: [Int] = []
}
extension ACDeviceLastData: Decodable {
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: ACDeviceCodingKeys.self)
if let ints: [Int] = try? (container.decodeIfPresent([Int].self, forKey: .DA) ?? []) {
// will pass here when `DA` is null or an array of ints
DA = ACDeviceLastDataBody()
DAasInts = ints
} else {
// null is already handled above
DA = try container.decode(ACDeviceLastDataBody.self, forKey: .DA)
DAasInts = []
}
}
}
您可能希望以不同方式表示您的数据,例如从整数数组创建 ACDeviceLastDataBody
。
我正在使用以下模型解码对象
struct ACDeviceLastData {
var DA: ACDeviceLastDataBody = ACDeviceLastDataBody()
}
struct ACDeviceLastDataBody {
var amOn: Bool = false
var enabledZones: [Int] = []
var fanSpeed: Int = 0
var mode: Int = 0
var tempTarget: Float = 0.00
}
extension ACDeviceLastData: Decodable {
init(from decoder: Decoder) throws {
//Create Container
let container = try decoder.container(keyedBy: ACDeviceCodingKeys.self)
//Decode Data
DA = try container.decodeIfPresent(ACDeviceLastDataBody.self, forKey: .DA) ?? ACDeviceLastDataBody()
}
}
extension ACDeviceLastDataBody: Decodable {
init(from decoder: Decoder) throws {
//Create Container
let container = try decoder.container(keyedBy: ACDeviceCodingKeys.self)
//Decode Data
amOn = try container.decodeIfPresent(Bool.self, forKey: .amOn) ?? false
enabledZones = try container.decodeIfPresent([Int].self, forKey: .enabledZones) ?? []
fanSpeed = try container.decodeIfPresent(Int.self, forKey: .fanSpeed) ?? 0
mode = try container.decodeIfPresent(Int.self, forKey: .mode) ?? 0
tempTarget = try container.decodeIfPresent(Float.self, forKey: .tempTarget) ?? 0.00
}
}
问题在于 DA
的值并不总是相同的类型。它有时可以采用整数数组的格式,有时采用 ACDevieLastDataBody 的格式。我试过做一个 do-try-catch 但无法完全弄清楚如何让它工作(如果这是正确的做法)
我的问题是,当它是一个整数数组时,我将如何在解码器不抛出的情况下解码它们。非常感谢任何帮助。提前谢谢你。
您需要在 init(from decoder: Decoder)
这是一个简单的转换,注意类型可能不完全相同,因此兼容性由您安排,您的负担。
我看不到 JSON,但是 JSON 代码非常容易做到,因为 JSON 类型在原子级别总是很简单。
希望对您有所帮助...
今天过得愉快!
首先,您必须选择一种存储数据的方式。为简单起见,我们将 Int
的数组存储为单独的 属性:
struct ACDeviceLastData {
var DA: ACDeviceLastDataBody = ACDeviceLastDataBody()
var DAasInts: [Int] = []
}
extension ACDeviceLastData: Decodable {
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: ACDeviceCodingKeys.self)
if let ints: [Int] = try? (container.decodeIfPresent([Int].self, forKey: .DA) ?? []) {
// will pass here when `DA` is null or an array of ints
DA = ACDeviceLastDataBody()
DAasInts = ints
} else {
// null is already handled above
DA = try container.decode(ACDeviceLastDataBody.self, forKey: .DA)
DAasInts = []
}
}
}
您可能希望以不同方式表示您的数据,例如从整数数组创建 ACDeviceLastDataBody
。