1

I'm attempting to slowly migrate an Objective C app over to Swift and have started to create new classes -

public class MapsAPI : NSObject {

    let delegate: MapsAPIResponseDelegate

    public init(managerWithDelegate delegate: MapsAPIResponseDelegate) {
        self.delegate = delegate
    }

}

Now in my Objective C .m file I've declared #import MyTarget-Swift.h and in my .h I've added @class MapsAPI which all seems fine however I'm not sure what the Objective C initialisation code should look like. I've tried -

MapsAPI *api = [[MapsAPI alloc] initWithManagerWithDelegate: self];

But that errors with -

No visible @interface for 'MapsAPI' declares the selector 'initWithManagerWithDelegate:'

I've tried looking at the definition of my MyTarget-Swift.h but all that shows is -

SWIFT_CLASS("_TtC4What7MapsAPI")
@interface MapsAPI : NSObject
- (nonnull instancetype)init SWIFT_UNAVAILABLE;
@end

Is there something I'm doing wrong here?

Chris Edgington
  • 2,937
  • 5
  • 23
  • 42
  • 5
    You have to add @objc to all methods which are to be exposed to Objective-C. See https://stackoverflow.com/questions/47210873/bulk-fix-hundreds-of-selector-not-exposed-to-objective-c-errors-in-xcode-9-or or https://stackoverflow.com/questions/44762460/swift-4-this-class-is-not-key-value-coding-compliant – Martin R Apr 09 '18 at 20:51
  • Nice and simple. Thanks. – Chris Edgington Apr 09 '18 at 21:31

1 Answers1

4

You may choose to add @objcMembers to your class declaration:

public class @objcMembers MapsAPI : NSObject {

    let delegate: MapsAPIResponseDelegate

    public init(managerWithDelegate delegate: MapsAPIResponseDelegate) {
        self.delegate = delegate
    }
}

Alternatively (or additionally... who am I to judge) you can mark your initializer as being exposed to Objective-C

public class MapsAPI : NSObject {

    let delegate: MapsAPIResponseDelegate

    @objc public init(managerWithDelegate delegate: MapsAPIResponseDelegate) {
        self.delegate = delegate
    }
}

And if you want to, you can also explicitly define the Objective-C selector used:

public class MapsAPI : NSObject {

    let delegate: MapsAPIResponseDelegate

    @objc(initManagerWithDelegate:)
    public init(managerWithDelegate delegate: MapsAPIResponseDelegate) {
        self.delegate = delegate
    }
}
Scott Thompson
  • 22,629
  • 4
  • 32
  • 34
  • I thought public classes and methods were automatically available to Objective-C from the auto-generated bridging header? – Shawn Nov 08 '19 at 17:00