In a larger ObjC/Swift-mixed codebase I have an ObjC protocol MyObjCProtocol <NSObject>
that other ObjC classes need to conform to. It declares a string property @property (copy) NSString *myString
.
Now, one of my Swift objects has a property conformsToObjCProtocol
that is declared conforming to this protocol:
let conformsToObjCProtocol: MyObjCProtocol
This all works well.
But when I try to observe myString
using Combine like this:
let cancellable = conformsToObjCProtocol.publisher(for: \.myString).sink { print($0) }
I get an error Value of type 'any MyObjCProtocol' has no member 'publisher'
.
I believe it should work because MyObjCProtocol is declared conforming to NSObject. I did add MyObjCProtocol.h to the bridging header too so that's not it. I can't rewrite the protocol in Swift because I need ObjC classes to conform to it. What can I do about this?
The Objective-C protocol is imported into Swift as a protocol that requires conformance to NSObjectProtocol
. It does not require the conformer to inherit NSObject
.
If you declare the property like this:
let conformsToObjCProtocol: MyObjCProtocol & NSObject
then this can be observed using a NSObject.KeyValueObservingPublisher
.
NSObject.KeyValueObservingPublisher(
object: conformsToObjCProtocol, keyPath: \.myString, options: []
).sink { ... }
The publisher
method unfortunately cannot be used here because of how it is declared. The declaration requires that you call it on a concrete type.