Json 类型';区域数据';不符合协议';可编码';

Json 类型';区域数据';不符合协议';可编码';,json,swift,codable,Json,Swift,Codable,当我为我的JSON文件建立模型时,我得到了这两个错误 1) 我在AreaData结构中得到了一致性错误 2) “AnyObject不能用作符合协议Decodable的类型,因为Decodable在初始化器中有静态要求”错误 我试过几种方法,但找不到正确的解决办法。如何为这个嵌套/复杂的JSON创建合适的模型 这是我的JSON文件。此数据是嵌套的 [ { "ID": "01", "Name": "Area 01", "parentId": n

当我为我的JSON文件建立模型时,我得到了这两个错误

1) 我在AreaData结构中得到了一致性错误

2) “
AnyObject
不能用作符合协议
Decodable
的类型,因为
Decodable
在初始化器中有静态要求”错误

我试过几种方法,但找不到正确的解决办法。如何为这个嵌套/复杂的JSON创建合适的模型

这是我的JSON文件。此数据是嵌套的

[
    {
        "ID": "01",
        "Name": "Area 01",
        "parentId": null,
        "sublevel": [
            {
                "ID": "01-01",
                "Name": "Building 01",
                "On": "",
                "Off": "",
                "parentId": "01",
                "sublevel": [
                    {
                        "ID": "01-01-01",
                        "Name": "Flat 01",
                        "On": "",
                        "Off": "",
                        "parentId": "01-01",
                        "sublevel": []
                    }
                ]
            },
            {
                "ID": "01-02",
                "Name": "Building 02",
                "On": "01",
                "Off": "03",
                "parentId": "01",
                "sublevel": [
                    {
                        "ID": "01-02-01",
                        "Name": "Flat 01",
                        "On": "",
                        "Off": "",
                        "parentId": "01-02",
                        "sublevel": []
                    },
                    {
                        "ID": "01-02-02",
                        "Name": "Flat 02",
                        "On": "01",
                        "Off": "02",
                        "parentId": "01-02",
                        "sublevel": []
                    },
                    {
                        "ID": "01-02-03",
                        "Name": "Flat 03",
                        "On": "02",
                        "Off": "12",
                        "parentId": "01-02",
                        "sublevel": [
                            {
                                "ID": "01-02-03-01",
                                "Name": "Room 01",
                                "On": "",
                                "Off": "",
                                "parentId": "01-02-03",
                                "sublevel": []
                            },
                            {
                                "ID": "01-02-03-02",
                                "Name": "Room 02",
                                "On": "",
                                "Off": "",
                                "parentId": "01-02-03",
                                "sublevel": []
                            },
                            {
                                "ID": "01-02-03-03",
                                "Name": "Room 03",
                                "On": "02",
                                "Off": "03",
                                "parentId": "01-02-03",
                                "sublevel": []
                            },
                            {
                                "ID": "01-02-03-04",
                                "Name": "Room 04",
                                "On": "",
                                "Off": "",
                                "parentId": "01-02-03",
                                "sublevel": []
                            },
                            {
                                "ID": "01-02-03-05",
                                "Name": "Room 05",
                                "On": "01",
                                "Off": "",
                                "parentId": "01-02-03",
                                "sublevel": []
                            }
                        ]
                    },
                    {
                        "ID": "01-02-04",
                        "Name": "Flat 04",
                        "On": "12",
                        "Off": "03",
                        "parentId": "01-02",
                        "sublevel": []
                    },
                    {
                        "ID": "01-02-05",
                        "Name": "Flat 05",
                        "On": "02",
                        "Off": "",
                        "parentId": "01-02",
                        "sublevel": []
                    }
                ]
            },
            {
                "ID": "01-03",
                "Name": "Building 03",
                "On": "02",
                "Off": "01",
                "parentId": "01",
                "sublevel": []
            },
            {
                "ID": "01-04",
                "Name": "Building 04",
                "On": "",
                "Off": "",
                "parentId": "01",
                "sublevel": []
            }
        ]
    }
]
这是我的模型课

import Foundation
struct AreaData : Codable {

    let iD : String?
    let name : String?
    let parentId : AnyObject?
    let sublevel : [Sublevel]?

    enum CodingKeys: String, CodingKey {
        case iD = "ID"
        case name = "Name"
        case parentId = "parentId"
        case sublevel = "sublevel"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        iD = try values.decodeIfPresent(String.self, forKey: .iD)
        name = try values.decodeIfPresent(String.self, forKey: .name)
        parentId = try values.decodeIfPresent(AnyObject.self, forKey: .parentId)
        sublevel = try values.decodeIfPresent([Sublevel].self, forKey: .sublevel)
    }

}

struct Sublevel : Codable {

    let on : String?
    let iD : String?
    let name : String?
    let off : String?
    let parentId : String?
    let sublevel : [Sublevel]?

    enum CodingKeys: String, CodingKey {
        case on = "On"
        case iD = "ID"
        case name = "Name"
        case off = "Off"
        case parentId = "parentId"
        case sublevel = "sublevel"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        on = try values.decodeIfPresent(String.self, forKey: .on)
        iD = try values.decodeIfPresent(String.self, forKey: .iD)
        name = try values.decodeIfPresent(String.self, forKey: .name)
        off = try values.decodeIfPresent(String.self, forKey: .off)
        parentId = try values.decodeIfPresent(String.self, forKey: .parentId)
        sublevel = try values.decodeIfPresent([Sublevel].self, forKey: .sublevel)
    }

}
试试这个

 struct AreaDataModel: Codable {
    let id, name: String
    let parentID: String? // AnyObject can't conform to Encodable protocol .  
    let sublevel: [Sublevel]

    enum CodingKeys: String, CodingKey {
        case id = "ID"
        case name = "Name"
        case parentID = "parentId"
        case sublevel
    }
}

// MARK: - Sublevel
struct Sublevel: Codable {
    let id, name, on, off: String
    let parentID: String
    let sublevel: [Sublevel]

    enum CodingKeys: String, CodingKey {
        case id = "ID"
        case name = "Name"
        case on = "On"
        case off = "Off"
        case parentID = "parentId"
        case sublevel
    }
}

typealias AreaData = [AreaDataModel]
我推荐简单快速的工具


问题是由于
任何对象
引起的
Codabe
不支持任何类似
Any
AnyObject
的内容。您需要显式指定类型

在您添加的JSON响应中,
parentId
null
String
。因此,您可以使用
String?
作为其类型,即

struct AreaData : Codable {
    let parentId : String? //here.....
    //rest of the code....
}
此外,如果属性和键完全匹配,则无需在
enum CodingKeys
中明确指定
case
rawValue
。因此,
struct AreaData
中的
CodingKeys
必须

enum CodingKeys: String, CodingKey {
    case iD = "ID"
    case name = "Name"
    case parentId, sublevel
}
此外,不需要
init(来自解码器:解码器)
。这是因为您没有在其中执行任何特定的解析。直接解析将由
Codable
本身处理

因此,
struct AreaData
应该如下所示:

struct AreaData : Codable {
    let iD : String?
    let name : String?
    let parentId : String?
    let sublevel : [Sublevel]?

    enum CodingKeys: String, CodingKey {
        case iD = "ID"
        case name = "Name"
        case parentId, sublevel
    }
}
对结构子级进行类似的更改

此外,仅当您希望对数据进行编码和解码时,才使用
Codable
。如果您想要单一功能,即编码或解码,请使用
可编码
可解码

推荐:

由于
AreaData
Sublevel
包含几乎相同类型的数据,因此可以使用单个
struct
对该JSON进行
解码,即


问题是由于任何对象造成的。Codabe不支持任何对象。您需要显式指定类型。在SubLevel parentId中,parentId是一个字符串,有没有理由相信它在顶级(AreaData)中是不同的?
struct AreaData: Decodable {
    let iD : String?
    let name : String?
    let parentId : String?
    let sublevel : [AreaData]?
    let on : String?
    let off : String?

    enum CodingKeys: String, CodingKey {
        case iD = "ID"
        case name = "Name"
        case on = "On"
        case off = "Off"
        case parentId, sublevel
    }
}