@protocol X <NSObject> but valueForKey undefined?

Using a protcol defined in a ObjectiveC header file, then using it in some Swift 4 code. The Swift code does not natively allow 'value(forKeyL key)' unless I explicitly add that method to the protocol:


X.h:

@protocol X <NSObject>
...
- (id _Nullable)valueForKey:(NSString *)key; // cannot compile Y.swift without this
@end


Y.swift:

init(info: X) {
  ...
  guard let value = info.value(forKey: key) else { continue }
  ...
}


Why?

Accepted Reply

`value(forKey:)` (in Objective-C `valueForKey:`) is defined as an instance method of `NSObject` class, not for `NSObject` protocol.


You cannot use `valueForKey:` for protocol `X` even in Objective-C when the method is not defined in the protocol:

- (void)test:(id<X>) obj {
    [obj valueForKey:@"..."]; // <- error: no known instance method for selector 'valueForKey:'
}


So, something like this should work without explicitly adding the method to the protocol:

    init(info: NSObject & X) {
        //...
        guard let value = info.value(forKey: key) else { continue }
        //...
    }

Replies

`value(forKey:)` (in Objective-C `valueForKey:`) is defined as an instance method of `NSObject` class, not for `NSObject` protocol.


You cannot use `valueForKey:` for protocol `X` even in Objective-C when the method is not defined in the protocol:

- (void)test:(id<X>) obj {
    [obj valueForKey:@"..."]; // <- error: no known instance method for selector 'valueForKey:'
}


So, something like this should work without explicitly adding the method to the protocol:

    init(info: NSObject & X) {
        //...
        guard let value = info.value(forKey: key) else { continue }
        //...
    }

Just a short note in case someone else is looking for the same advice. More detail: a Swift Module that gets passed an NSObject that meets the described protocol. What appears to work (it compiles!) is to use a type alias - to avoid having to add NSObject & X everywhere:


typealias XX = NSObject & X
init(info: XX) {
...


Thanks again for the assistance!!!