I've just started learning Combine and am quite confused with behaviour of KVO publishers. They just do not publish any events except for the initial value. Here is the sample code I used:
@objc class SampleClass: NSObject {
@objc var name: NSString = "1"
}
var a = SampleClass()
let kvoPublisher = a.publisher(for: \.name)
.sink(receiveCompletion: {
print("completion \($0)")
}, receiveValue: { newVal in
print("new val - \(newVal)")
})
a.name = "2"
a.name = "3"
print("Finished; publisher = \(kvoPublisher) | a.name = \(a.name)")
The console output is
new val - 1
Finished; publisher = Combine.AnyCancellable | a.name = 3
Could you please explain what am I missing here and how to fix it?
Thanks.
You also need to mark the property as
dynamicin order for it to be KVO compliant.publisher(for:)only works with KVO compliant properties, since it uses KVO under the hood.Once you do that, the KVO publisher emits the updated values as expected.
For more information on
@objcvs@objc dynamic, see this Q&A.Bear in mind that you should only use KVO publishers when interacting with code that you cannot change. When you want to observe property values of types that you control, use
@Publishedinstead.