Я столкнулся с проблемой, из-за которой я не могу сделать RealmOptional совместимым с быстрой новой функцией Codable с декодером json.
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, потому что я написал расширение для 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)
Но если я удалю ключ numberOfStudents
из данных json, которые должны быть объектом RealmOptional, он выдаст ошибку и не будет декодировать, потому что RealmOptional не является быстрым необязательным, поэтому декодер считает, что в данных json должен быть ключ. В JSONDecoder
он не пытается декодировать, если ключ отсутствует в json, а свойство объявлено как необязательное. Он просто переходит к другим клавишам.
До сих пор я не отменял инициализатор, потому что у нас были все поддерживающие расширения для RealmOptional
Realm Lists
и т. Д. Но теперь мне нужно переопределить init(from decoder: Decoder)
, чтобы декодировать его вручную, а модель 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
, чтобы нам не пришлось переопределять инициализаторы.