swiftcombine

How Do I get new value and old value with NSObject.KeyValueObservingPublisher


I try to convert KVO code to use Combine that I encountered a problem about get old value and new value at the same time.
I don't have any idea about that.
Can anyone help me?

class Person: NSObject {
    @objc dynamic var name: String
    
    init(name: String) {
        self.name = name
    }
}

let person = Person(name: "John")
let cancellable = person.publisher(for: \.name, options: [.initial, .new, .old])
    .sink { value in
        print("Person's name: \(value)")
    }
person.name = "Allen"

// Result
// --------------------
// Person's name: John    works for .initial
// Person's name: Allen   works for .new

Solution

  • You need .scan operator in this case, try this:

    let person = Person(name: "John")
    let cancellable = person.publisher(for: \.name)
        .scan(("", ""), { ($0.1, $1) }) //<- here
        //.filter { $0.0 != "" } //<- add here if you don't need to listen the empty string initializer
        .sink { value in
            print("Person's name: \(value)")
        }
    
    
    //Output:
    //Person's name: ("", "John")
    //Person's name: ("John", "Allen")