swift可编码阵列中的不同键

时间:2017-11-16 03:22:48

标签: arrays json swift codable

我刚刚使用Swift 4 Codable从设备解码我的json数据。 我得到了如下的JSON数据

{
    "CmdBegin": true,
    "GatewayMac": "1",
    "CmdName": "DevListUpdate",
    "DevItem": [
        {
            "DevMac": "00000000000000B0",
            "DevName": "Software Button",
            "DevAction": [
                {
                    "DevName": "A",
                    "Value": -1000
                },
                {
                    "DevName": "B",
                    "Value": -1000
                }
            ]
        },
        {
            "DevMac": "00000000000000B1",
            "DevName": "Software Button",
            "DevAction": [
                {
                    "DevName": "C",
                    "Value": -1000
                },
                {
                    "DevName": "D",
                    "Value": -1000
                }
            ]
        },
        {
            "DevMac": "00:17:88:01:00:fa:2a:5d-0b",
            "DevName": "E",
            "DevSubItem": [
                {
                    "SubIndex": 0,
                    "Cmdset": 0,
                    "SubStatus": "1"
                },
                {
                    "SubIndex": 1,
                    "Cmdset": 512,
                    "SubStatus": "14"
                }
            ]
        }
    ]
}

我使用Swift 4

    struct DevResults: Codable{
        var CmdBegin: Bool
        var GatewayMac: String
        var CmdName: String
        var CmdEnd: Bool
        var DevItem: [DevList]
    }
    struct DevList: Codable {
        var DevMac: String
        var DevName: String
        var DevAction: [DevActionList]
        var DevSubItem: [DevSubItemList]
    }
    struct DevActionList: Codable{
        var DevMac: String
        var DevName: String
        var DevType: Int
        var DevProtocol: Int
        var ActionIdx: Int
        var Value: Int
    }
    struct DevSubItemList: Codable{
        var SubIndex: Int,
        var Cmdset: Int,
        var SubStatus: String
    }
    let decoder = JSONDecoder()
    if receiveData.contains("DevListUpdate"){
        let data = receiveData.data(using: .utf8)!
        do {
            let locList = try JSONDecoder().decode(DevResults.self, from: data)
            print(locList)
        } catch let error {
            print(error)
        }
    }

}

但我不能使用正确的JSON格式,因为DevItem Array中有不同的键。我试着用 var DevItem: Array<Dictionary<String: AnyObject>>

是否有针对不同键值JSON文件的解决方案?

1 个答案:

答案 0 :(得分:0)

你错过了几件事 -

  
      
  • 你应该DevSubItem&amp; DevAction属性为Optional
  •   
  • 您需要实施init(from decoder: Decoder) throws   解码您的JSON
  •   

改进了您的代码 -

     let jsonExample2 = """
{
    "CmdBegin": true,
    "GatewayMac": "1",
    "CmdName": "DevListUpdate",
    "DevItem": [
        {
            "DevMac": "00000000000000B0",
            "DevName": "Software Button",
            "DevAction": [
                {
                    "DevName": "A",
                    "Value": -1000
                },
                {
                    "DevName": "B",
                    "Value": -1000
                }
            ]
        },
        {
            "DevMac": "00000000000000B1",
            "DevName": "Software Button",
            "DevAction": [
                {
                    "DevName": "C",
                    "Value": -1000
                },
                {
                    "DevName": "D",
                    "Value": -1000
                }
            ]
        },
        {
            "DevMac": "00:17:88:01:00:fa:2a:5d-0b",
            "DevName": "E",
            "DevSubItem": [
                {
                    "SubIndex": 0,
                    "Cmdset": 0,
                    "SubStatus": "1"
                },
                {
                    "SubIndex": 1,
                    "Cmdset": 512,
                    "SubStatus": "14"
                }
            ]
        }
    ]
}

""".data(using: .utf8)!
    struct DevResults: Codable{
        var CmdBegin: Bool
        var GatewayMac: String
        var CmdName: String
        var DevItem: [DevList]
    }
    struct DevList: Codable {
        var DevMac: String
        var DevName: String
        var DevAction: [DevActionList]?
        var DevSubItem: [DevSubItemList]?
    }
    struct DevActionList: Codable{
        var DevName: String
        var Value: Int
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            DevName = try values.decode(String.self, forKey: .DevName)
            Value = try values.decode(Int.self, forKey: .Value)
        }
    }
    struct DevSubItemList: Codable{
        var SubIndex: Int
        var Cmdset: Int
        var SubStatus: String
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            SubIndex = try values.decode(Int.self, forKey: .SubIndex)
            Cmdset = try values.decode(Int.self, forKey: .Cmdset)
            SubStatus = try values.decode(String.self, forKey: .SubStatus)
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()


        let jsonDecoder = JSONDecoder()
        do {
            let modelResult = try jsonDecoder.decode(DevResults.self,from: jsonExample2)
            if modelResult.DevItem.count > 0 {
                print("dev Name is \(modelResult.DevItem.first?.DevName ?? "-")")
            }

        } catch {
            print(error)
        }
    }
}

Apple文档 - Using JSON with Custom Types您还可以通过该链接从Apple下载示例代码。