【发布时间】:2020-03-04 17:56:18
【问题描述】:
我在 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 接收到已经保存在 DB 中的数据时,我需要更新它。据我了解,已实现primarykey
realm?.add(Item, update: .modified)
将更新具有相同主记录的现有记录。 具有类 Item 的对象的属性已更新,但类别的 List 未更新。
我尝试获取保存在数据库中的现有类别列表,并通过调用 savedItem.categories.removeAll() 改变了与 savedItem 关联的类别对象,并使用 savedItem.categories.append(objectsIn: itemFromAPI.categories) 添加了新类别
当我用
realm?.add(Item, update: .modified)
领域崩溃抛出异常 - “RLMException 原因:尝试创建具有现有主键值的类型的对象”
所以我尝试使用
删除类别realm?.delete(Category)
然后添加与项目关联的修改后的类别,这正在工作。
我已将类别嵌套到多个级别,并通过再次获取它来更新它们,删除它们并再次读取它们被证明是一种痛苦。这就是更新记录在领域中的工作方式吗?
我可以通过简单地将新对象分配给一个项目并使用
来更新与一个项目相关的嵌套类别吗?realm?.add(Item, update: .modified)
要像添加新项目那样更新记录?
任何回复将不胜感激。
【问题讨论】:
-
我想你在这里问的是如何使领域列表属性可编码,对吧?如果是这样,那么这里已经多次询问和回答了。请参阅this question and answer 和this question。检查这些,看看它们是否有帮助,因为 List 对象不能直接编码或解码
-
没有。我的问题是如何使用 realm?.add(Item, update: .modified) 函数更新领域列表属性。它似乎没有更新 List 属性。我是否应该获取现有的数据库条目然后删除条目,使用相同的主键创建新条目以进行更新,或者我是否可以简单地构建包含新值列表的主对象并使用设置了更新标志的领域添加功能更新它们?
-
我想我有一个答案。让我知道是否需要澄清。
标签: ios realm realm-list