如何使RealmSwift RealmOptional与Swift Codable兼容?

如何使RealmSwift RealmOptional与Swift Codable兼容?,第1张

概述我面临一个问题,我无法通过json解码器使RealmOptional与 swift新的Codable功能兼容. Cosider以下Realm对象. class School: Object, Codable { @objc dynamic var id: Int64 = 0 @objc dynamic var name: String? var numberOfStud 我面临一个问题,我无法通过Json解码器使RealmOptional与 swift新的Codable功能兼容.

CosIDer以下Realm对象.

class School: Object,Codable {    @objc dynamic var ID: Int64 = 0    @objc dynamic var name: String?    var numberOfStudents = RealmOptional<Int64>()    var classes = List<Class>()    enum CodingKeys: String,CodingKey {       case ID       case name       case numberOfStudents       case classes    }}class Class: Object,Codable {    var name: String?    var numberOfStudents = RealmOptional<Int64>()}

在这里我们可以将类声明为Codable,因为我在this gist的帮助下为RealmOptinal编写了一个扩展.但问题是当解码器解码Json时.

考虑一下这个Json

let JsonData = """[    "ID": 1234,"name": "Shreesha","numberOfStudents": nil,"classes": {       "name": "Class V","numberOfStudents": 12    }]""".data(using: .utf8)!

在这个Json中,所有数据都被传递,并且这与代码完美地解码.

let decoder = JsONDecoder()let decoded = try! decoder.decode(School.self,from: JsonData)

但是如果我从应该是RealmOptional对象的Json数据中删除numberOfStudents键,它将抛出一个错误并且它不会解码因为RealmOptional不是一个快速可选的,所以解码器认为Json数据中应该有一个键.在JsONDecoder中,它不会尝试解码,如果Json中没有键,并且属性被声明为可选.它只是跳到其他键.

到目前为止,我没有覆盖初始化器,因为我们拥有RealmOptional Realm Lists等的所有支持扩展.但是现在我必须覆盖init(来自解码器:解码器)以手动解码它并且Realm模型具有50多个属性它(你知道我的意思).

如果我们覆盖初始化器,我觉得使用JsONDecoder没有意义,因为手动工作比使用JsONDecoder更多.

required convenIEnce init(from decoder: Decoder) throws {    self.init()    let container = try decoder.container(keyedBy: CodingKeys.self)    ID = try container.decodeIfPresent(Int64.self,forKey: .ID) ?? 0    name = try container.decodeIfPresent(String?.self,forKey: .name) ?? ""    numberOfStudents = try container.decodeIfPresent(RealmOptional<Int64>.self,forKey: .numberOfStudents) ?? RealmOptional<Int64>()    let classesArray = try container.decode([Class].self,forKey: .classes)    classes.append(objectsIn: classesArray)}

因此,有人可以建议我使用替代解决方案使RealmOptional与JsONDecoder兼容,这样我们就不必覆盖初始化器.

解决方法 您可以采取以下措施来解决问题.创建一个支持解码的新类,并将RealmOptional作为其属性.

class Optionalint64: Object,Decodable {    private var numeric = RealmOptional<Int64>()    required public convenIEnce init(from decoder: Decoder) throws {        self.init()        let singleValueContainer = try decoder.singleValueContainer()        if singleValueContainer.decodeNil() == false {            let value = try singleValueContainer.decode(Int64.self)            numeric = RealmOptional(value)        }    }    var value: Int64? {        return numeric.value    }    var zeroOrValue: Int64 {        return numeric.value ?? 0    }}

然后,不要在学校班级中使用RealmOptional,而是使用这个新的Optionalint64类,

class School: Object,Codable {    @objc dynamic var ID: Int64 = 0    @objc dynamic var name: String?    @objc dynamic  var numberOfStudents: Optionalint64?    var classes = List<Class>()    enum CodingKeys: String,CodingKey {       case ID       case name       case numberOfStudents       case classes    }}

请注意,现在使用RealmNumeric而不是使用RealmOptional?其类型为Optional.由于它是可选的,因此自动解码使用decodeIfPresent方法来解码可选值.如果它不存在于Json中,则该值将变为零.

总结

以上是内存溢出为你收集整理的如何使RealmSwift RealmOptional与Swift Codable兼容?全部内容,希望文章能够帮你解决如何使RealmSwift RealmOptional与Swift Codable兼容?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1003229.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存