How to call Swift from Objective-C


Gerriet M. Denkmann
 

I have a Swift project called TestSwift:

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate
{
@IBOutlet weak var window: NSWindow!

func applicationDidFinishLaunching(_ aNotification: Notification)
{
print(#function + " self \(self)") // self <TestSwift.AppDelegate: 0x600000000820>
let a = OClass()
a.soSomething(for:self)
}

public func abc() { print(#function) }
}

I read somewhere that Xcode would generate a TestSwift-Swift.h header for me.
My Xcode (Version 9.4.1 (9F2000)) did not.

So I made:

@interface AppDelegate : NSObject
-(void)abc;
@end

Here is my Objective-C class:

#import "OClass.h"
#import "TestSwift-Swift.h"
@implementation OClass
- (void)soSomethingFor: (AppDelegate *)sender;
{
NSLog(@"%s sender %@",__FUNCTION__, sender); // sender <TestSwift.AppDelegate: 0x600000000820>
[ sender abc ]; // -[TestSwift.AppDelegate abc]: unrecognized selector sent to instance 0x600000000820
}
@end

Compiles fine, but gets this “unrecognized selector” error at run time.


What am I doing wrong?

Gerriet.


Gerriet M. Denkmann
 

On 15 Jul 2018, at 15:45, Gerriet M. Denkmann <g@mdenkmann.de> wrote:

I have a Swift project called TestSwift:

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate
{
@IBOutlet weak var window: NSWindow!

func applicationDidFinishLaunching(_ aNotification: Notification)
{
print(#function + " self \(self)") // self <TestSwift.AppDelegate: 0x600000000820>
let a = OClass()
a.soSomething(for:self)
}

public func abc() { print(#function) }
This does work:
@objc public func abc() { print(#function) }

}

I read somewhere that Xcode would generate a TestSwift-Swift.h header for me.
My Xcode (Version 9.4.1 (9F2000)) did not.
Well, it did, but hidden somewhere in DerivedData/…


So I made:

@interface AppDelegate : NSObject
-(void)abc;
@end

Here is my Objective-C class:

#import "OClass.h"
#import "TestSwift-Swift.h"
@implementation OClass
- (void)soSomethingFor: (AppDelegate *)sender;
{
NSLog(@"%s sender %@",__FUNCTION__, sender); // sender <TestSwift.AppDelegate: 0x600000000820>
[ sender abc ]; // -[TestSwift.AppDelegate abc]: unrecognized selector sent to instance 0x600000000820
}
@end
Now it works.

Sorry for the noise.

Gerriet