列表不符合可编码
因此,我正在使用领域,并且两个模型之间具有以下关系:A unit has many tests
:
So, I'm using realm and I have the following relationship between two models: A unit has many tests
:
// Unit model
class Unit: Object, Decodable {
@objc dynamic var id: String = ""
...
let tests = List<Test>()
enum CodingKeys: String, CodingKey {
case id
...
//case tests = "complete_control_tests"
}
convenience required init(from decoder: Decoder) throws {
self.init()
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(String.self, forKey: .id)
...
if let arr = try container.decodeIfPresent(Array<Test>.self, forKey: .tests) {
tests.append(objectsIn: arr)
} else {
self.tests.append(objectsIn: [])
}
}
}
// Test model
class Test: Object, Decodable {
@objc dynamic var id: String = ""
@objc dynamic var room_control_id: String = ""
enum CodingKeys: String, CodingKey {
case id
case room_control_id = "room_control_id"
}
}
当注释tests
属性时,我可以正确地解析该模型的json输出.但是,当我取消注释时,会出现以下错误:
When the tests
property is commented, I can properly parse the json output for that model. But then when I uncommented it, I have the following errors:
Swift.Encodable:12:17: Protocol requires function 'encode(to:)' with type 'Encodable'
Models/Unit.swift:27:6: Cannot automatically synthesize 'Encodable' because 'List<Test>' does not conform to 'Encodable'
有没有一种方法可以使Codable和Realm变得更好玩?
Is there a way to make Codable and Realm play nice?
您的代码有几个问题.首先,如果只想实现init(from:)
方法,而不是encode
方法,则声明符合Decodable
而不是Codable
.其次,在创建自己的init(from:)
方法时需要实现CodingKeys
,并且还需要从便捷初始化器中调用类的指定初始化器.
There are several issues with your code. First of all, if you only want to implement the init(from:)
method, but not the encode
method, declare conformance to Decodable
rather than Codable
. Secondly, you need to implement CodingKeys
when creating your own init(from:)
method and you also need to call a designated initializer of your class from a convenience initializer.
在初始化程序中也不需要else
子句,因为tests
已经被初始化为空的List
,并且向其添加空数组也没有意义.
There's also no need for the else
clause in the initializer, since tests
is initialized as an empty List
already and appending an empty array to it makes no sense.
class Unit: Object, Decodable {
@objc dynamic var id: String = ""
let tests = List<Test>()
private enum CodingKeys: String, CodingKey {
case id, tests
}
convenience required init(from decoder: Decoder) throws {
self.init()
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(String.self, forKey: .id)
if let arr = try container.decodeIfPresent(Array<Test>.self, forKey: .tests) {
tests.append(objectsIn: arr)
}
}
}