json - 类型 'AreaData' 不符合协议(protocol) 'Encodable'

标签 json swift codable

当我为 JSON 文件创建模型时,出现这两个错误。

1) 我在 AreaData 结构中遇到了符合错误

2) “AnyObject 不能用作符合协议(protocol) 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]

I recommend this tool simple and fast .

关于json - 类型 'AreaData' 不符合协议(protocol) 'Encodable',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57176854/

相关文章:

javascript - jQuery.when() 似乎没有在等待

java - Jackson 直接将嵌套列表作为 POJO

java - 有没有一种简单的方法可以使用 Spring MVC 和 JSON 更新基于 Spring-Data 的对象

ios - 施加力后的 ARKit 获取节点的位置

ios - 根目录下的 Codable Handle 动态 key

java - 如何使用 Java 更新 JSON 文件中的嵌套 JSON 对象?

ios - 在 Alamofire 闭包中返回 Bool

ios - 以编程方式获取导航栏的高度

swift - 如何一起使用Codable和Coredata?

json - 使用 Swift 4 的 Codable 进行类型转换