类型 'AreaData' 不符合协议 'Encodable'

Type 'AreaData' does not conform to protocol 'Encodable'

当我为 JSON 文件制作模型时,出现了这两个错误。

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

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

我尝试了几种方法,但找不到正确的解决方案。我怎样才能为这个nested/complexJSON制作一个合适的模型?

这是我的 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": []
            }
        ]
    }
]

这是我的模型class

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]

I recommend this tool simple and fast .

问题是由于 AnyObjectCodabe 不支持 AnyAnyObject 之类的内容。您需要明确指定类型。

在您添加的JSON响应中,parentIdnullString。所以,你可以使用 String? 作为它的类型,即

struct AreaData : Codable {
    let parentId : String? //here.....
    //rest of the code....
}

此外,如果 属性,则无需在 enum CodingKeys 中明确指定 caserawValue key 完全匹配。所以struct AreaData中的CodingKeys一定是,

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

此外,init(from decoder: Decoder) 不是必需的。这是因为您没有在其中进行任何特定的解析。直接解析将由 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
    }
}

也对 struct Sublevel 进行类似的更改。

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

建议:

由于 AreaDataSublevel 包含几乎相同类型的数据,您可以使用单个 structdecodeJSON,即

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