arrays - 快速编码数组中的不同键

标签 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 数组中有不同的键。我试着用 var DevItem: Array<Dictionary<String: AnyObject>>

对于不同的key-value JSON文件有什么解决方案吗?

最佳答案

您遗漏的一些东西 -

  • You should make DevSubItem & DevAction properties as Optional
  • You need to implement init(from decoder: Decoder) throws for decoding your 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 下载示例代码。

关于arrays - 快速编码数组中的不同键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47321040/

相关文章:

java - 按项目子字符串对数组排序

javascript - 问题 : can't access Json data inside the html template, AngularJS

javascript - Node js中的JSON错误未定义为发布数据的前缀

javascript - 循环访问 .json 对象

ios - 将结构从 ObjC 传递到 Swift

ios - 使用 Floaty 库显示矩形按钮

php - 来自mysql的多维数组用于数据可视化

arrays - Laravel 5 中 all() 和 toArray() 的区别

arrays - 在设备上运行时调用错误中的额外参数

ios - Swift - 在条件下执行 performSegue