objective-cswift

No visible @interface for 'MySwiftClass' declares the selector 'addX:andY'


We are trying to reference Swift methods inside an Objective-C implementation.

Swift class:

import Foundation
@objc class MySwiftClass: NSObject {
    override init() {
        super.init()
    }

    func sayHello() -> Void {
        print("hello");
    }

    func addX(x:Int, andY y:Int) -> Int {
     return x+y
    }
}

Objective-C implementation (Objective-c.m):

#import "ProductModuleName-Swift.h"
MySwiftClass* getData = [[MySwiftClass alloc]init];
[getData sayHello] //works
[getData addX:5 addY:5] //No visible @interface for 'MySwiftClass' declares selector 'addX:addY'

The last line of code gives the following error:

No visible @interface for 'MySwiftClass' declares selector 'addX:addY'


Solution

  • If you command-click on "ProductModuleName-Swift.h" in the Xcode source file editor then you can see how the Swift methods are mapped to Objective-C.

    In your case that would be

    @interface MySwiftClass : NSObject
    - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
    - (void)sayHello;
    - (NSInteger)addXWithX:(NSInteger)x andY:(NSInteger)y;
    @end
    

    which is called as

    MySwiftClass* getData = [[MySwiftClass alloc]init];
    [getData sayHello];
    NSInteger result = [getData addXWithX:5 andY:5];
    

    A better Swift 3 method name might be

    func add(x: Int, y:Int) -> Int
    

    because x is already the argument (external) name of the first parameter. You can also add an @objc() attribute to the Swift definition to control the Objective-C name. For example, with

    @objc(addX:andY:)
    func add(x: Int, y: Int) -> Int {
        return x+y
    }
    

    it would be called from Objective-C as

    NSInteger result = [getData addX:5 andY:5];