[英]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]
The problem is due to AnyObject
. 问题是由于
AnyObject
。 Codabe
doesn't support anything like Any
or AnyObject
. Codabe
不支持Any
或AnyObject
类的东西。 You need to specify the type explicitly. 您需要明确指定类型。
In the JSON response you added, the parentId
is either null
or String
. 在您添加的JSON响应中 ,
parentId
为null
或String
。 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, 所以
CodingKeys
在struct 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. 如果您需要单一功能,即编码或解码 ,请改用
Encodable
或Decodable
。
Recommendation: 建议:
Since the AreaData
and Sublevel
contain almost same kind of data, you can use a single struct
to decode
that JSON , ie 由于
AreaData
和Sublevel
含有几乎相同类型的数据,你可以使用一个单一的struct
来decode
是JSON,即
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.