Zusammenspiel von Swift und Objective-C-Code

von @ralfebert · aktualisiert am 9. Juli 2021

Swift-Code und Objective-C-Code können über den Bridging Header bzw. einen automatisch generierten Header zusammenarbeiten.

Objective-C-Klassen in Swift verwenden

In den Build Settings des Xcode-Projektes kann ein Objective-C Bridging Header konfiguriert werden:

Bridging Header Build Setting

Um den Bridging Header anzulegen, am besten temporär eine Objective-C Klasse via New File » Cocoa Touch Class anlegen - Xcode fragt dann nach, ob ein Bridging Header erstellt werden soll:

Create Bridging Header

Eine Objective-C-Klasse, die in einem Header deklariert ist, z.B. GreeterObjc in GreeterObjc.h:

@interface GreeterObjc : NSObject

- (void) greetWithName:(NSString *)name;

@end

kann im Bridging Header für die Verwendung in Swift importiert werden:

//
//  Use this file to import your target's public headers that you would like to expose to Swift.
//

#import "GreeterObjc.h"

Soweit die Methodenbenennung gemäß Objective-C Konventionen erfolgt (methodWithParam1:param2:), werden entsprechend passende Swift-Methodensignaturen erzeugt. In Swift könnte die Methode aus dem Beispiel folgendermaßen aufgerufen werden:

GreeterObjc().greet(withName: "Bob")

Swift-Klassen in Objective-C verwenden

Klassen die von NSObject erben oder mit @objc markiert werden, und Methoden die als @objc markiert sind, werden mit einem automatisch generierten Header [Modulname]-Swift.h für Objective-C-Code zugänglich gemacht:

@objc
class GreeterSwift : NSObject {

    @objc func greet(name: String) {
        print("Hello from Swift to \(name)")
    }

}

In Objective-C-Code kann nun der Header [Modulname]-Swift.h importiert werden, um Swift-Klassen in Objective-C zu verwenden, z.B.:

#import "ObjcViewController.h"
#import "SwiftObjcExample-Swift.h"

@implementation ObjcViewController

- (IBAction) greet {
    [[[GreeterSwift alloc] init] greetWithName:@"Bob"];
}

@end

Achtung: Der Header [Modulname]-Swift.h darf nicht in Header-Dateien importiert werden, sondern nur in .m-Dateien, da sonst Zyklen im Build auftreten. Wenn Swift-Typen in Headern benötigt werden, diese mit einer Forward-Deklaration @class ... deklarieren.

Einschränkungen

Alle Swift-Sprachfeatures, die keine Entsprechung in Objective-C haben, können nicht verwendet werden. Dies betrifft z.B. structs, enums ohne Int-RawType/mit Parametern und generische Typen. Soll in einem Projekt neuer Swift-Code aus altem Objective-C-Code aufgerufen werden, muss auf diese Features was die APIs betrifft verzichtet werden.

Weitere Informationen