Я использую Codable with Realm для iOS и обнаружил проблему с обновлением существующих записей, сохраненных в Realm. Данные состоят из списка элементов, каждый из которых имеет список категорий, а каждая категория имеет описание.
Так выглядят мои модели Realm Codable
class Items: Object, Decodable {
@objc dynamic var id: String = ""
@objc dynamic var name: String = ""
let categories = List<Categories>()
@objc dynamic var desc: Desc?
override static func primaryKey() -> String? {
return "id"
}
var hasSubCategories: Bool {
if self.categories.count > 0 {
return true
}
return false
}
enum CodingKeys: String, CodingKey {
case id
case name
case desc
case categories
}
required init() {
super.init()
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(String.self, forKey: .id)
name = try container.decode(String.self, forKey: .name)
desc = try (container.decodeIfPresent(Desc, forKey: .desc))
let categoriesList = try container.decodeIfPresent(List<Categories>.self, forKey: .categories) ?? List<Categories>()
categories.append(objectsIn: categoriesList)
super.init()
}
}
class Categories: Object, Decodable {
@objc dynamic var id: String = ""
@objc dynamic var name: String = ""
@objc dynamic var desc: Desc?
let categories = List<Categories>()
override static func primaryKey() -> String? {
return "id"
}
var hasSubCategories: Bool {
if categories.count > 0 {
return true
}
return false
}
enum CodingKeys: String, CodingKey {
case id
case name
case categories
}
required init() {
super.init()
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(String.self, forKey: .id)
name = try container.decode(String.self, forKey: .name)
desc = try (container.decodeIfPresent(Desc, forKey: . desc))
let categoriesList = try container.decodeIfPresent(List<Categories>.self, forKey: .categories) ?? List<Categories>()
categories.append(objectsIn: categoriesList)
super.init()
}
}
Я добавляю новые элементы, полученные из API, со следующим кодом
let realm = try? Realm()
for item in ItemsFromAPI {
do {
try realm?.write {
realm?.add(item)
}
}
}
Когда данные уже сохранены в БД получен от API, мне нужно его обновить. Насколько я понимаю, с primarykey реализовано
realm?.add(Item, update: .modified)
обновит существующую запись, которая имеет тот же основной. Свойства объекта с классом Item обновляются, но список <> категорий не обновляется.
Я попытался получить существующий список категорий, сохраненных в базе данных, и изменил объект категории, связанный с saveItem, вызвав savedItem.categories.removeAll()
и добавил новые категории с помощью savedItem.categories.append(objectsIn: itemFromAPI.categories)
Когда я сохраняю это с помощью
realm?.add(Item, update: .modified)
Сбой области, выдавая исключение - «Причина RLMException: Попытка создать объект типа с существующим значением первичного ключа»
Поэтому я попытался удалить категорию с помощью
realm?.delete(Category)
, а затем добавил измененную категорию, связанную с элементом, и это работает.
Я вложил категории в несколько уровней и обновил их путем выборки. это снова, удаление их и чтение их снова оказывается болью. Так ли работает обновление записей в области?
Можно ли обновить вложенную категорию, связанную с элементом, просто назначив новый объект для элемента и используя
realm?.add(Item, update: .modified)
для обновления записей как это сделано для добавления нового элемента?
Буду признателен за любой ответ.