Сохранение массива объектов в Realm с помощью Decodable
У меня есть класс, который соответствует протоколу Decodable (выборка данных из API), и я хотел бы сохранить его в базе данных Realm. Проблема возникает, когда одним из моих свойств является массив (список). Это говорит Cannot automatically synthesize Decodable because List<Item> does not conform to Decodable
Каков наилучший способ обойти эту проблему? Realm поддерживает только массивы примитивных типов.
вот мой класс:
class PartValue: Object, Decodable {
@objc dynamic var idetifier: Int = 0
let items = List<Item>()
}
1 ответ
Используя долгожданные условные соответствия, реализованные в Swift 4.1, вы можете просто объявить List
соответствовать Decodable
если его Element
соответствует Decodable
,
extension List: Decodable where List.Element: Decodable {
public convenience init(from decoder: Decoder) throws {
self.init()
var container = try decoder.unkeyedContainer()
let array = try container.decode(Array<Element>.self)
self.append(objectsIn: array)
}
}
Чтобы это работало для вашего конкретного случая, вы должны убедиться, что Item
также соответствует Decodable
,
Если вам также нужно Encodable
соответствие, просто расширить List
чтобы поддержать это также.
extension List: Encodable where List.Element: Encodable {
public func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(contentsOf: Array(self))
}
}
Решение Давида не сработало для меня полностью. Я должен был настроить решение вместо того, чтобы заменить decoder.unkeyedContainer()
в decoder.singleValueContainer()
ниже решение.
extension List: Decodable where List.Element: Decodable {
public convenience init(from decoder: Decoder) throws {
self.init()
let container = try decoder.singleValueContainer()
let array = try container.decode([Element].self)
self.append(objectsIn: array)
}
}