我在iOS上使用Codable和Realm,并发现在更新已保存在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接收到已保存在数据库中的数据时,我需要更新它。据我理解,应该使用主键实现更新。
realm?.add(Item, update: .modified)
将会更新具有相同主键的现有记录。类为Item的对象属性已被更新,但是categories类型为List<>的对象没有被更新。
我尝试获取数据库中保存的现有categories列表,并通过调用savedItem.categories.removeAll()
改变与savedItem关联的categories对象,并添加新的categories,方法是savedItem.categories.append(objectsIn: itemFromAPI.categories)
。当我保存这些更改时:
realm?.add(Item, update: .modified)
Realm崩溃并抛出异常 - “RLMException原因:尝试创建一个已经存在主键值的对象”
我尝试着移除这个类别,使用方法是
realm?.delete(Category)
然后添加与项目相关的修改后的类别,目前已经运行正常。
我有多个级别的嵌套类别,通过再次获取它们,删除并重新添加它们来更新它们,这证明是一种痛苦的方式。在realm中,更新记录是这样工作的吗?
我能否通过简单地将新对象分配给项目并使用来更新与项目相关的嵌套类别
realm?.add(Item, update: .modified)
如何更新记录,就像添加新项目时一样?
非常感谢您的回复。