【问题标题】:Swift 4 parsing json numeric keys with 1+n amountSwift 4 解析 1+n 数量的 json 数字键
【发布时间】:2023-03-16 16:30:01
【问题描述】:

我还在学习这个 Codable/Decodable Swift 4 中的新功能,用于 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} ....
}

【问题讨论】:

    标签: json swift4


    【解决方案1】:

    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})
        }
    }
    

    【讨论】:

      【解决方案2】:
      var json = """
      {
        "temperature": {
          "poolTemp" : 85,
          "spaTemp"  : 85,
          "airTemp"  : 75
        },
        "circuit": {
          "1": {
            "number": 1,
            "numberStr": "circuit1",
            "name": "SPA"
          },
          "2": {
            "number": 2,
            "numberStr": "circuit2",
            "name": "POOL LIGHT"
          }
        }
      }
      """.data(using: .utf8)!
      
      struct Weather :Codable {
          let temperature:Temperature
          let circuit:Circuit
      }
      struct Temperature :Codable{
          let poolTemp:Int 
          let spaTemp:Int 
          let airTemp:Int
      }
      struct Circuit:Codable {
        let one:Circuits 
        let two:Circuits
        enum CodingKeys:String,CodingKey {
            case one = "1" 
            case two = "2"
        }
      }
      struct Circuits: Codable {
          let number: Int 
          let numberStr : String
          let name: String
      }
      do {
      let decoder = try JSONDecoder().decode(Weather.self , from: json) 
       print(decoder)
      }catch {
          print("Error decoding Data")
      }
      

      【讨论】:

      • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
      猜你喜欢
      • 2019-08-05
      • 2018-05-24
      • 2018-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多