Swift 4 Codable Realm对象子类
试图将我的一些代码库切换到Swift 4的新的漂亮的Codable
协议.我的设置如下所示:
trying to switch some of my codebase over to Swift 4's new nifty Codable
protocol. My setup looks something like this:
class Base: Object, Codable {
dynamic var id: String = ""
dynamic var timestamp: String = ""
private enum CodingKeys: String, CodingKey {
case id = "_id"
case timestamp = "timestamp"
}
}
class User: Base {
dynamic var name: String = ""
private enum CodingKeys: String, CodingKey {
case name = "name"
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.name = try container.decode(String.self, forKey: .name)
try super.init(from: decoder)
}
}
我有一个符合Codable
的基本领域对象类,还有一个Base
的子类,它也有自己的编码键.我在User
子类上重写init(decoder:)
来映射我的其他编码键,然后调用super.init(decoder:)
来映射Base
的编码键.但是,一旦我覆盖init(decoder:)
,就会出现以下错误:
I have a base realm object class that conforms to Codable
, and a subclass of Base
that also has it's own coding keys. I override init(decoder:)
on the User
subclass to map my additional coding keys, then call super.init(decoder:)
to map Base
's coding keys. However, once I override init(decoder:)
I get the following errors:
- 必需的初始化程序"init()"必须由"Base"的子类提供
- 必需的初始值设定项'init(realm:schema :)'必须由'Base'的子类提供
- 必需的初始值设定项'init(value:schema :)'必须由'Base'的子类提供
- required initializer 'init()' must be provided by subclass of 'Base'
- required initializer 'init(realm:schema:)' must be provided by subclass of 'Base'
- required initializer 'init(value:schema:)' must be provided by subclass of 'Base'
我不确定要解决这些问题的正确方法.
I'm not sure what the correct way is to go about fixing these issues.
您不能覆盖init()
或Realm Object
的其他初始化程序.您可以改为使用便捷初始化程序.然后,您将无法调用super.init(from:)
,因此请定义一个方法来解码超类的属性,例如Base.decode(from:)
.
You cannot override init()
or other initializers of Realm Object
. You can use convenience initializer instead. Then you cannot call super.init(from:)
, so define a method that decodes superclass' properties like Base.decode(from:)
.
请参见以下代码示例:
class Base: Object, Codable {
dynamic var id: String = ""
dynamic var timestamp: String = ""
private enum CodingKeys: String, CodingKey {
case id = "_id"
case timestamp = "timestamp"
}
func decode(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.id = try container.decode(String.self, forKey: .id)
self.timestamp = try container.decode(String.self, forKey: .timestamp)
}
}
class User: Base {
dynamic var name: String = ""
private enum CodingKeys: String, CodingKey {
case id = "_id"
case timestamp
case name = "name"
}
required convenience init(from decoder: Decoder) throws {
self.init()
try decode(from: decoder)
let container = try decoder.container(keyedBy: CodingKeys.self)
self.name = try container.decode(String.self, forKey: .name)
}
}