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

使用SwiftUI中的ObservedRealmObject更新领域对象上的附加字段,swiftui,realm,combine,Swiftui,Realm,Combine,Xcode 12.5、iOS 14.5、macOS 11.3 假设我在SwiftUI应用程序中有这样一个简单的领域类: class Item: Object, ObjectKeyIdentifiable{ @objc dynamic var id = "" @objc dynamic var name = "" @objc dynamic var updated = Date() } 我使用@ObservedRealmObject将对象传递到

Xcode 12.5、iOS 14.5、macOS 11.3

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

class Item: Object, ObjectKeyIdentifiable{
  @objc dynamic var id = ""
  @objc dynamic var name = ""
  @objc dynamic var updated = Date()
}
我使用
@ObservedRealmObject
将对象传递到视图中,在视图中我可以通过将对象绑定到
文本字段
视图来编辑其
名称
属性,如下所示:

struct DetailView: View {
  @ObservedRealmObject var item: Item

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

  }
}
当我编辑字段时,
name
属性会随着我的键入而更新,并且领域会实时更新

但是,每当修改对象时,我还想用新的
Date()
时间戳更新
updated
属性。由于写入事务由
@ObservedRealmObject
自动管理,因此我不清楚如何实现这一点


每次更改
名称
(或任何其他附加属性)时,我如何更改
更新的

可以通过很多方法实现这一点;从简单地在按下“保存”按钮时更新更新的属性,到使用KVO观察对象名称属性的更改,再到向对象objc属性添加一个可通过处理的Swift“前端”

让我们使用使用Swift计算属性的第三个选项,并修改问题中的项

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"
    }
}
需要注意的几点:

名称
属性被私有化,名称更改为
\u name
。我这样做是为了不让您意外地设置它并绕过Swift实现

然后,我们添加了一个新的Swift
name
属性,作为由
\u name
支持的领域属性的“前端”属性

使用便利功能创建项时,让i=item(name:“item 0”)或在写入块中设置
someItem.name=“Updated name”
计算属性设置域属性,并填充
Updated
属性

set {
   _name = newValue
   updated = Date()
}

这应该与
@ObservedRealmObject

无缝配合,我没有具体的答案,但听起来
更新的
变量更像是一个计算属性,这意味着它会根据其他属性上的操作进行更改。我想您有第二个视图控制器,可能有一个“保存”按钮?如果是这样,您可以在保存时更新属性。或者,您可以将观察者添加到每当属性更改时激发的对象,并在其中更新它。您可以使用领域属性支持的Swift对象通过计算属性来实现这一点。领域对象是KVO,因此您也可以使用一些老式的KVO魔术来更新它。您是否尝试过在
name
上使用
didSet
observer?例如,
@objc dynamic var name=“{didSet{updated=Date()}}
@robmayoff我认为这行不通。领域对象和属性是Objc-请注意每个对象的
@Objc dynamic
。willSet/didSet是独立于KVO的轻量级(Swift)属性观察器,KVO是领域对象所需的。您尝试过吗?@robmayoff是的,谢谢。我认为@Jay建议在我表单的“保存”操作上手动设置
updated
,这是最简单的解决方案。这很好,谢谢!