When using Core Data I would override willSave
on NSManagedObject
to compute alastModified
value on a model object. This allowed one simple method to check changed values and set a date if necessary.
It is possible set lastModified
in SwiftData, but the approaches I have found all have drawbacks when compared to the previous approach.
Hide saved model properties behind transient versions
private var textSaved: String = ""
var text: String {
get { textSaved }
set {
textSaved = newValue
lastModified = .now
}
}
I could hide every property that should update the lastModified
behind a computed value, but this requires additional code for each new property and obfuscates the model definition.
Update all properties through an update function
func update<T>(keyPath: ReferenceWritableKeyPath<Player, T>, to value: T)
Paul Hudson notes a workaround where any changes are made to the model through an update function that takes a keyPath. This will add complexity to every view that wants to modify model properties, and also leaves those properties open to change through other approaches.
Use ModelContext.willSave
ModelContext
sends a notification when it is about to save. This could be caught in .onReceive in a view or perhaps in some model-holding singleton, then ALL changes queried and dealt with accordingly. Perhaps the best approach here would to add willSave
to all model objects so code external to the model isn't doing the lastModified
logic.
This last solution feels like the best way forward that I know (ideally avoiding any .onReceive code in views). Should I prefer another solution or are there better ones I have missed?