I need an observable property on certain view controllers in my application, I’m trying to standardize this through a protocol.
protocol MyProtocol: UIViewController {
dynamic var observeMe: Bool { get set }
}
But when trying to observe the property like so:
let viewController = UIViewController()
if let observableViewController = viewController as? MyProtocol {
observableViewController.observe(.observeMe, options: [.old, .new], changeHandler: { object, change in
// Do something
})
}
Xcode throws the compiler error:
"Member ‘observe’ cannot be used on value of protocol type
‘MyProtocol’; use a generic constraint instead"
2
Answers
You can try this –
You can declare a function and apply the generic constraint to it.
In Swift 5.7 you can simply do:
Then you can call it:
Prior to Swift 5.7,
some MyProtocol
is not supported and you need to use type erasure:And call it like so:
By the way, you will receive a warning reading:
Passing reference to non-'@objc dynamic' property 'observeMe' to KVO method 'observe(_:options:changeHandler:)' may lead to unexpected behavior or runtime trap
But in your case you can’t declare it as
@objc
because an@objc
protocol can’t inherit from a non-protocol type.