I'm creating a SwiftUI app with various View Model objects to support the views. On some views, where the user can leave without saving changes, e.g. 'Cancel' I want to prompt a confirmation if the underlying view model has any changes. Some of the view models have many properties that can be set/changed, so I'm trying to avoid having to change each @Published property to have a didChange method to capture the change as it will be a lot of ugly plumbing which feels unnecessary. Since subscribers to the object can detect changes, I was wondering if there was a way that I could hook into that myself so that I can react to published changes to the object and then set the hasChanges flag.

Any help/advice is very much appreciated.

class MySimpleViewModel: ObservableObject {
    @Published var firstName: String
    @Published var lastName: String
    @Published var age: Int
    // I want to be able to set this automatically by hooking into the pub/sub pipeline.
    var hasChanges: Bool = false
    
    init (firstName: String, lastName: String, age: Int) {
        self.firstName = firstName
        self.lastName = lastName
        self.age = age
    }
}
1

There are 1 answers

0
AudioBubble On

One easy solution is, by changing this section of your code to:

@Published private(set) var hasChanges: Bool = false

init(firstName: String, lastName: String, age: Int) {
  self.firstName = firstName
  self.lastName = lastName
  self.age = age

  objectWillChange
    .first()
    .map { true }
    .assign(to: &$hasChanges)
}

But, because anything can subscribe to objectWillChange, you may want to reconsider bothering to store that information within the object itself.