当我为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)
}
}
答案 0 :(得分:0)
尝试一下,
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]
我建议使用this工具方便快捷。
答案 1 :(得分:0)
问题是由于AnyObject
引起的。 Codabe
不支持Any
或AnyObject
之类的东西。您需要明确指定类型。
在您添加的 JSON响应中,parentId
是null
或String
。因此,您可以使用String?
作为其类型,即
struct AreaData : Codable {
let parentId : String? //here.....
//rest of the code....
}
此外,如果属性和密钥rawValue中明确指定case
的{{1}} >完全匹配。因此enum CodingKeys
中的CodingKeys
必须是
struct AreaData
此外,不需要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
或Encodable
。
推荐
:由于Decodable
和AreaData
包含几乎相同类型的数据,因此您可以使用单个Sublevel
到struct
那个 JSON ,即
decode