简体   繁体   English

类型“ AreaData”不符合协议“可编码”

[英]Type 'AreaData' does not conform to protocol 'Encodable'

When I make a model for my JSON file, I get these two errors. 当我为JSON文件建立模型时,会出现这两个错误。

1) I got the conform error in AreaData struct 1)我在AreaData结构中遇到了一致错误

2) " AnyObject cannot be used as a type conforming to protocol Decodable because Decodable has static requirements" error in initialiser. 2) AnyObject程序中出现“ AnyObject不能用作符合协议Decodable的类型,因为Decodable具有静态要求”错误。

I have tried several ways but I cannot find the correct solution. 我尝试了几种方法,但是找不到正确的解决方案。 How can I make a proper model for this nested/complex JSON? 如何为该嵌套/复杂的JSON创建合适的模型?

Here is my JSON file. 这是我的JSON文件。 This data is nested 此数据是嵌套的

[
    {
        "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": []
            }
        ]
    }
]

And this is my model 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)
    }

}

try this, 尝试这个,

 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 . 我建议工具简单快捷。

The problem is due to AnyObject . 问题是由于AnyObject Codabe doesn't support anything like Any or AnyObject . Codabe不支持AnyAnyObject类的东西。 You need to specify the type explicitly. 您需要明确指定类型。

In the JSON response you added, the parentId is either null or String . 在您添加的JSON响应中parentIdnullString So, you can use String? 那么,您可以使用String? as its type, ie 作为其类型,即

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

Also, there is no need to specify the rawValue of the case explitly in enum CodingKeys if the property and the key has an exact match. 此外,没有必要指定rawValue的的case在explitly enum CodingKeys如果属性密钥具有精确匹配。 So the CodingKeys in struct AreaData must be, 所以CodingKeysstruct AreaData必须是,

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

Moreover, init(from decoder: Decoder) is not required. 此外,不需要init(from decoder: Decoder) This is because you're not doing any specific parsing inside it. 这是因为您没有在其中进行任何特定的解析。 Direct parsing will be handled by the Codable itself. 直接解析将由Codable本身处理。

So, struct AreaData should look like, 因此, 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
    }
}

Make similar changes to struct Sublevel as well. struct Sublevel也进行类似的更改。

Also, use Codable only if you want to both encode and decode the data. 另外,仅当您要编码和解码数据时才使用Codable In case you want a single functionality ie either encode or decode , use Encodable or Decodable instead. 如果您需要单一功能,即编码或解码 ,请改用EncodableDecodable

Recommendation: 建议:

Since the AreaData and Sublevel contain almost same kind of data, you can use a single struct to decode that JSON , ie 由于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
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 类型“”不符合协议“可编码” - Type ' ' does not conform to protocol 'Encodable' 如果我在 swift 的结构中使用协议类型,我的结构不符合协议“可解码”/“可编码” - My structure does not conform to protocol 'Decodable' / 'Encodable' if I use protocol type in my structure in swift swift 将字典转换为 jsonString 错误:协议类型 'Any' 不能符合 'Encodable' 因为只有具体类型才能符合协议 - swift Convert dictionary to jsonString error : Protocol type 'Any' cannot conform to 'Encodable' because only concrete types can conform to protocols Argo:类型不符合“可解码”协议 - Argo: Type does not conform to protocol 'Decodable' 类型[String:String]不符合协议“ AnyObject” - type [String: String] does not conform to protocol 'AnyObject' SwiftUI-类型“服务”不符合协议“可解码” - SwiftUI - Type 'Service' does not conform to protocol 'Decodable' 类型“字符串”不符合协议“ NSCopying”-数组swift json错误 - Type 'String' does not conform to protocol 'NSCopying' - Array swift json Error Swift 4.2:类型“ T”不符合协议“可解码” - Swift 4.2 : Type 'T' does not conform to protocol 'Decodable' Swift,ObjectMapper:类型“用户”不符合协议“可映射” - Swift, ObjectMapper: Type 'User' does not conform to protocol 'Mappable' 如何在Swift 4可编码协议中使用JSON字典类型编码属性 - How to encode a property with type of JSON dictionary in Swift 4 encodable protocol
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM