在 SwiftUI 中使用 ObservedRealmObject 更新领域对象的附加字段

Update Additional Field on Realm Object with ObservedRealmObject in SwiftUI

Xcode 12.5,iOS 14.5,macOS 11.3

假设我在 SwiftUI 应用程序中有一个像这样的简单领域 class:

class Item: Object, ObjectKeyIdentifiable{
  @objc dynamic var id = ""
  @objc dynamic var name = ""
  @objc dynamic var updated = Date()
}

我使用 @ObservedRealmObject 将一个对象传递到视图中,我可以通过将它绑定到 TextField 视图来编辑它的 name 属性,如下所示:

struct DetailView: View {
  @ObservedRealmObject var item: Item

  var body: some View{
  
    TextField("Name...", $item.name)

  }
}

当我编辑该字段时,name 属性 会随着我的键入而更新,领域也会实时更新。

但我还想在对象被修改时用新的 Date() 时间戳更新 updated 属性。由于写入事务由 @ObservedRealmObject 自动管理,我不清楚如何完成此操作。

如何在每次更改 name(或任何其他附加 属性)时更改 updated

有很多方法可以做到这一点;从按下 'save' 按钮时简单地更新更新的 属性 到使用 KVO 观察对象名称 属性 的变化到添加 Swift 'front end'可以通过 Computed Properties.

处理的对象 objc 属性

让我们使用第三个选项,使用 Swift Computed Properties 并修改问题中的 Item。

class Item: Object, ObjectKeyIdentifiable{
    @objc dynamic var _id = UUID().uuidString
    @objc private dynamic var _name = ""
    @objc dynamic var updated = Date()
    
    var name: String {
        get {
            return _name
        }
        set {
            _name = newValue
            updated = Date()
        }
    }
    
    convenience init(name: String) {
        self.init()
        self.name = name
    }
    
    override static func primaryKey() -> String? {
        return "_id"
    }
}

注意几点:

领域 name 属性 已设为私有,名称更改为 _name。我这样做是为了防止您不小心设置它并绕过 Swift 实现。

然后我们添加了一个新的 Swift name 属性 作为 'front end' 属性 到由 [ 支持的领域 属性 =13=].

当使用便利函数 let i = Item(name: "Item 0") 创建项目或在写入块 someItem.name = "Updated name" 中设置项目时, name 计算 属性 设置领域 属性并且还填充 updated 属性

set {
   _name = newValue
   updated = Date()
}

应该@ObservedRealmObject

无缝协作