Note: Things have change since this answer was first written - see updates at the end!
Yeah, this does seam to be a bug... though, controlling Obj-C runtime names of methods does work:
Say we define a pair of minimal Obj-C and Swift classes that interact with each other:
Foo.swift
import Foundation @objc(SwiftFoo) class Foo { // inheriting from NSObject makes no difference in this case @objc(postcardFromSwift) class func postcard() -> String { return "Postcard from Swift!" } @objc(getMailInSwift) class func getMail() { if let hello = NSBar.postcard() { // NSBar is an Obj-C class (see below) println("Printed in Swift: \(hello)") } } }
NSBar.h
#import <Foundation/Foundation.h> @interface NSBar : NSObject + (NSString *)postcard; + (void)getMail; @end
NSBar.m
#import "NSBar.h" #import "ObjS-Swift.h" @implementation NSBar + (void)getMail { // notice that I am not referring to SwiftFoo in spite of @objc(SwiftFoo) printf("Printed in Objective C: %s", [[Foo postcardFromSwift] UTF8String]); } + (NSString *)postcard { return @"Postcard from Objective C!"; } @end
If we now call their class methods, say, from main.m:
#import <Cocoa/Cocoa.h> #import "NSBar.h" #import "ObjS-Swift.h" int main(int argc, const char * argv[]) { // notice that I am not referring to SwiftFoo in spite of @objc(SwiftFoo) [Foo getMailInSwift]; [NSBar getMail]; return NSApplicationMain(argc, argv); }
This prints the following:
// --> Printed in Swift: Postcard from Objective C! // --> Printed in Objective C: Postcard from Swift!
But it shouldn't have! Foo should only be visible to Obj-C as SwiftFoo since that is what @objc(SwiftFoo) is promising to do. Indeed, using SwiftFoo triggers the Use of undeclared identifier compiler error instead. The fact that this did work for method names, leaves little doubt that this is a bug. I am just amazed that you seem to be the first to ask about it! Plus one for that!
And yes:
// <#ModuleName#>-Swift.h SWIFT_CLASS("SwiftFoo") @interface Foo + (NSString *)postcardFromSwift; + (void)getMailInSwift;
... does seam to be inverted for the class name, yet this is how that macro works – see WWDC video Swift Interoperability In Depth (c. 45 min and c. 48 min into the video). The relevant documentation is Exposing Swift Interfaces in Objective-C.
Xcode 7 beta 4
The issue is now fixed (thanks to @ScottBerrevoets for the comment).
Xcode 7.1
(thanks to @Pang for the comment)
@objc class C { } // error: only classes that inherit from NSObject can be declared @objc
NSFoo?Use of undeclared identifier 'NSFoo'