Question on @objc protocol visibility from Swift code

hi! i witnessed an issue recently which led me to wonder a bit more deeply about the following Swift/Objc interop scenario:

  1. An @objc protocol is declared in Swift, in Module A
  2. A conforming objc type is declared in Objective-C in Module B
  3. The conforming objc type is used in Swift code in Module C

the specific setup surfacing the issue was a bit too complex to fully recreate here, but the gist is something like this:

// in Swift code in Module A
@objc public protocol MySwiftProto { func doSomething() }
// in Objective-C code in Module B
@import ModuleA;

@interface ObjcConformance: NSObject<MySwiftProto> { ... }
// interface in `.h`, impl in `.m`
// in Swift code in Module C
import ModuleA
import ModuleB

var conformance: ObjcConformance? = nil
conformance?.doSomething() // 🛑 Value of type 'ObjcConformance' has no member 'doSomething'

let dynamicCheck = ObjcConformance() as? MySwiftProto // cast succeeds
dynamicCheck?.doSomething() // works

i'm curious if this configuration is expected to work – that is, is it possible for the Objective-C type in this example to have its conformance 'seen' from the context outlined in 'Module C'? i've re-read the interop documentation, but i still don't quite understand what's going on here. thanks for your help!

Did you add your Objective-C headers in the bridging header ?

1 Like