我仍然在Swift 4中学习了Codable/Decodable
的新功能,用于JSON解析。
我能够构建一个结构并抓住温度键,但是Pump和其他类似的项目是数字字符串,可能是1到n。将它们解析为数组或字典的最佳方法是什么。我会假设一个for循环吗?
public struct ServerReponse: Codable {
let temperature: Temperature
let circuit: Circuit
}
public struct Circuit: Codable {
let number: Int
let numberStr: String
let name: String
let circuitFunction: String
let status: Int
let freeze: Int
let delay: Int
let friendlyName: String
let light: Light?
}
public struct Light: Codable {
let pump: Int
let position: Int
let colorStr: String
let color: Int
let colorSet: Int
let colorSetStr: String
let prevColor: Int
let prevColorStr: String
let colorSwimDelay: Int
let mode: Int
let modeStr: String
}
public struct Temperature : Codable {
let poolTemp: Int
let airTemp: Int
let poolSetPoint: Int
let heaterActive: Int
}
...
let poolData = try? JSONDecoder().decode(ServerReponse.self, from: data)
print(poolData?.temperature)
我在解析下一节“电路”时遇到问题,其中可能有1到许多数字键,然后电路本身位于每个数字键之下。
这是我正在使用的一些JSON ...
{
"temperature": {
"poolTemp": 85,
"spaTemp": 85,
"airTemp": 75,
"solarTemp": 0,
"freeze": 0,
"poolSetPoint": 82,
"poolHeatMode": 1,
"poolHeatModeStr": "Heater",
"spaSetPoint": 80,
"spaManualHeatMode": "Off",
"spaHeatMode": 0,
"spaHeatModeStr": "OFF",
"heaterActive": 0
},
"circuit": {
"1": {
"number": 1,
"numberStr": "circuit1",
"name": "SPA",
"circuitFunction": "Spa",
"status": 0,
"freeze": 0,
"macro": 0,
"delay": 0,
"friendlyName": "SPA"
},
"2": {
"number": 2,
"numberStr": "circuit2",
"name": "POOL LIGHT",
"circuitFunction": "Intellibrite",
"status": 0,
"freeze": 0,
"macro": 0,
"delay": 0,
"friendlyName": "POOL LIGHT",
"light": {
"position": 1,
"colorStr": "off",
"color": 0,
"colorSet": 12,
"colorSetStr": "Magenta",
"prevColor": 0,
"prevColorStr": "White",
"colorSwimDelay": 5,
"mode": 0,
"modeStr": "Off"
}
},
"3": {
"number": 3,
"numberStr": "circuit3",
"name": "AUX 2",
"circuitFunction": "Generic",
"status": 1,
"freeze": 0,
"macro": 0,
"delay": 0,
"friendlyName": "OUTLET - PINE TREE"
},
"4": {
"number": 4,
"numberStr": "circuit4",
"name": "AUX 3",
"circuitFunction": "Generic",
"status": 1,
"freeze": 0,
"macro": 0,
"delay": 0,
"friendlyName": "OUTLET - FOUNTAIN"
},
"5": {
"number": 5,
"numberStr": "circuit5",
"name": "AUX 4",
"circuitFunction": "Generic",
"status": 0,
"freeze": 0,
"macro": 0,
"delay": 0,
"friendlyName": "AUX 4"
},
"6": {
"number": 6,
"numberStr": "circuit6",
"name": "POOL",
"circuitFunction": "Pool",
"status": 1,
"freeze": 1,
"macro": 0,
"delay": 0,
"friendlyName": "POOL"
},
.... {more keys} ....
}
答案 0 :(得分:2)
键circuit
的值是一个字典。
如果您需要通过数字快速访问,请将该对象解码为[String:Circuit]
public struct ServerReponse: Codable {
let temperature: Temperature
let circuit: [String:Circuit]
}
如果数组更合适,请编写一个自定义初始化程序,该初始化程序还会将值映射到数组。
public struct ServerReponse: Codable {
let temperature: Temperature
let circuits: [Circuit]
private enum CodingKeys: String, CodingKey { case temperature, circuits = "circuit"}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
temperature = try container.decode(Temperature.self, forKey: .temperature)
let circuitData = try container.decode([String:Circuit].self, forKey: .circuits)
circuits = Array(circuitData.values).sorted(by: {$0.number < $1.number})
}
}