it-swarm.com.de

Wie rufe ich Objective-C-Code von Swift aus auf?

Wie nennt man in Swift Objective-C-Code?

Apple erwähnte, dass sie in einer Anwendung koexistieren könnten. Bedeutet dies, dass alte Klassen, die in Objective-C erstellt wurden, technisch wiederverwendet werden könnten, während neue Klassen in Swift erstellt werden?

920
David Mulder

Verwendung von Objective-C-Klassen in Swift

** Wenn Sie eine vorhandene Klasse haben, die Sie verwenden möchten, führen Sie Schritt 2 und dann weiter zu Schritt 5. (In einigen Fällen musste ich einer älteren Objective-C-Datei einen expliziten #import <Foundation/Foundation.h hinzufügen.) **

Schritt 1: Hinzufügen der Objective-C-Implementierung - .m

Fügen Sie Ihrer Klasse eine .m -Datei hinzu und nennen Sie sie CustomObject.m.

Schritt 2: Fügen Sie Bridging Header hinzu

Wenn Sie Ihre .m -Datei hinzufügen, wird wahrscheinlich eine Eingabeaufforderung angezeigt, die folgendermaßen aussieht:

Enter image description here

Klicken JA !

Wenn Sie die Eingabeaufforderung nicht sehen oder Ihren Überbrückungsheader versehentlich gelöscht haben, fügen Sie Ihrem Projekt eine neue .h -Datei hinzu und nennen Sie sie <#YourProjectName#>-Bridging-Header.h.

In einigen Situationen, insbesondere wenn Sie mit Objective-C-Frameworks arbeiten, fügen Sie keine Objective-C-Klasse explizit hinzu und Xcode kann den Linker nicht finden. Erstellen Sie in diesem Fall Ihre .h -Datei mit dem oben genannten Namen und stellen Sie dann sicher, dass Sie den Pfad in den Projekteinstellungen Ihres Ziels folgendermaßen verknüpfen:

Enter image description here

Hinweis

Es wird empfohlen, Ihr Projekt mit dem Makro $(SRCROOT) zu verknüpfen, damit es weiterhin funktioniert, wenn Sie Ihr Projekt verschieben oder mit anderen über ein Remote-Repository daran arbeiten. $(SRCROOT) kann als das Verzeichnis angesehen werden, das Ihre .xcodeproj-Datei enthält. Es könnte so aussehen:

$(SRCROOT)/Folder/Folder/<#YourProjectName#>-Bridging-Header.h

Schritt 3: Objective-C-Header hinzufügen - .h

Fügen Sie eine andere .h Datei hinzu und nennen Sie sie CustomObject.h.

Schritt 4: Erstellen Sie Ihre Objective-C-Klasse

In CustomObject.h

#import <Foundation/Foundation.h>

@interface CustomObject : NSObject

@property (strong, nonatomic) id someProperty;

- (void) someMethod;

@end

In CustomObject.m

#import "CustomObject.h"

@implementation CustomObject 

- (void) someMethod {
    NSLog(@"SomeMethod Ran");
}

@end

Schritt 5: Klasse zum Bridging-Header hinzufügen

In YourProject-Bridging-Header.h:

#import "CustomObject.h"

Schritt 6: Verwenden Sie Ihr Objekt

In SomeSwiftFile.Swift:

var instanceOfCustomObject: CustomObject = CustomObject()
instanceOfCustomObject.someProperty = "Hello World"
println(instanceOfCustomObject.someProperty)
instanceOfCustomObject.someMethod()

Es ist nicht erforderlich, explizit zu importieren. Dafür ist der Bridging-Header gedacht.

Verwendung von Swift Klassen in Objective-C

Schritt 1: Neue Swift Klasse erstellen

Fügen Sie Ihrem Projekt eine .Swift -Datei hinzu und nennen Sie sie MySwiftObject.Swift.

In MySwiftObject.Swift:

import Foundation

class MySwiftObject : NSObject {

    var someProperty: AnyObject = "Some Initializer Val"

    init() {}

    func someFunction(someArg:AnyObject) -> String {
        var returnVal = "You sent me \(someArg)"
        return returnVal
    }   
}

Schritt 2: Importieren Sie Swift Dateien in die ObjC-Klasse

In SomeRandomClass.m:

#import "<#YourProjectName#>-Swift.h"

Die Datei: <#YourProjectName#>-Swift.h sollte bereits automatisch in Ihrem Projekt erstellt werden, auch wenn Sie sie nicht sehen können.

Schritt 3: Verwenden Sie Ihre Klasse

MySwiftObject * myOb = [MySwiftObject new];
NSLog(@"MyOb.someProperty: %@", myOb.someProperty);
myOb.someProperty = @"Hello World";
NSLog(@"MyOb.someProperty: %@", myOb.someProperty);

// original
NSString * retString = [myOb someFunction:@"Arg"];
// xcode10 expands the external arg here
NSString * retString = [myOb someFunctionWithSomeArg:@"Arg"];|

NSLog(@"RetString: %@", retString);

Hinweis:

1. CodeCompletion verhielt sich nicht so genau, wie ich es gerne hätte. Auf meinem System schien das Ausführen eines schnellen Builds mit "cmd + r" dabei zu helfen, Swift einen Teil des Objective-C-Codes zu finden und umgekehrt.

2. Wenn Sie einem älteren Projekt eine .Swift -Datei hinzufügen und die folgende Fehlermeldung erhalten: dyld: Library not loaded: @rpath/libswift_stdlib_core.dylib, versuchen Sie es vollständig Neustart von Xcode .

3. Während es ursprünglich möglich war, reine Swift Klassen in Objective-C mit dem @objc Präfix zu verwenden, ist dies nach Swift 2.0 nicht mehr möglich. Die ursprüngliche Erklärung finden Sie im Bearbeitungsverlauf. Wenn diese Funktion in zukünftigen Swift Versionen wieder aktiviert wird, wird die Antwort entsprechend aktualisiert.

1329
Logan

Siehe Apples Anleitung zu Verwenden von Swift mit Cocoa und Objective-C . Dieses Handbuch behandelt die Verwendung von Objective-C- und C-Code aus Swift und umgekehrt und enthält Empfehlungen zum Konvertieren eines Projekts oder zum Mischen und Anpassen von Objective-C/C- und Swift -Teilen in einem bestehenden Projekt.

Der Compiler generiert automatisch die Syntax Swift zum Aufrufen von C-Funktionen und Objective-C-Methoden. Wie in der Dokumentation zu sehen ist, hat dieses Ziel-C:

UITableView *myTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];

wird zu diesem Swift Code:

let myTableView: UITableView = UITableView(frame: CGRectZero, style: .Grouped)

Xcode erledigt diese Übersetzung auch im Handumdrehen - Sie können Open Quickly verwenden, während Sie eine Swift -Datei bearbeiten und einen Objective-C-Klassennamen eingeben, und Sie gelangen zu einer Swift-ified-Version des Klassenheaders . (Sie können dies auch abrufen, indem Sie auf ein API-Symbol in einer Swift -Datei klicken.) Und die gesamte API-Referenzdokumentation in iOS 8 und OS X) v10.10 (Yosemite) Entwicklerbibliotheken sind sowohl in Objective-C- als auch in Swift-Formularen sichtbar (z. B. UIView ).

116
rickster

Hier finden Sie eine schrittweise Anleitung zur Verwendung von Objective-C-Code (in diesem Fall ein von einem Drittanbieter bereitgestelltes Framework) in einem Swift-Projekt:

  1. Fügen Sie eine beliebige Objective-C-Datei zu Ihrem Swift-Projekt hinzu , indem Sie Datei -> Neu -> Neue Datei -> Objective-C-Datei wählen . Beim Speichern fragt Xcode , ob Sie einen Überbrückungsheader hinzufügen möchten. Wählen Sie ' Ja '. Gif: Hinzufügen einer leeren Datei zum Projekt und Generieren eines Bridging-Headers http://www.derrrick.com/stackoverflow/1-empty-file.gif

In einfachen Schritten:

  1. Eine Eingabeaufforderung wird angezeigt, und klicken Sie dann auf OK. Wenn sie nicht angezeigt wird, erstellen wir sie manuell wie folgt: Erstellen Sie eine Header-Datei aus der iOS-Quelle und geben Sie den Namen ProjectName-Bridging-Header ein (Beispiel: Test -Bridging-Header), und gehen Sie dann zur Build-Einstellung im Compiler-Code Swift -> Objective-C-Bridge. Fügen Sie den Namen der Objective-C-Bridge hinzu. (Test/Test-Bridging-Header.h). Ja, das ist komplett.

  2. Löschen Sie optional die von Ihnen hinzugefügte Objective-C-Datei (oben im GIF-Bild als "any" bezeichnet). Du brauchst es nicht mehr.

  3. Öffnen Sie die Bridging-Header-Datei - der Dateiname hat die Form [YourProject] -Bridging-Header.h . Es enthält einen von Xcode bereitgestellten Kommentar. Fügen Sie eine Codezeile für die Objective-C-Datei hinzu, die Sie einschließen möchten , z. B. ein Framework eines Drittanbieters. Um beispielsweise Mixpanel zu Ihrem Projekt hinzuzufügen, müssen Sie der Bridging-Header-Datei die folgende Codezeile hinzufügen:

    #import "Mixpanel.h"
  4. Jetzt können Sie in jeder Swift -Datei vorhandenen Objective-C-Code in der Swift -Syntax (in In diesem Beispiel können Sie Mixpanel-SDK-Methoden usw. aufrufen. Sie müssen sich damit vertraut machen, wie Xcode Objective-C in Swift übersetzt. Apples Anleitung ist eine schnelle Lektüre. Oder sehen Sie sich diese Antwort für eine unvollständige Zusammenfassung an.

Beispiel für Mixpanel:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    Mixpanel.sharedInstanceWithToken("your-token")
    return true
}

Das ist es!

Hinweis: Wenn Sie die Überbrückungsheaderdatei aus Ihrem Projekt entfernen , gehen Sie unbedingt zu Build Settings und entfernen Sie den Wert für " Objective-C Bridging Header "unter" Swift Compiler - Code Generation ".

59
derrrick

Sie können den Nizza Beitrag lesen Swift & Cocoapods. Grundsätzlich müssen wir eine Bridging-Header-Datei erstellen und alle Objective-C-Header dort ablegen. Und dann müssen wir in unseren Build-Einstellungen darauf verweisen. Danach können wir den Objective-C-Code verwenden.

let manager = AFHTTPRequestOperationManager()
manager.GET(
  "http://example.com/resources.json",
  parameters: nil,
  success: { (operation: AFHTTPRequestOperation!,
              responseObject: AnyObject!) in
      println("JSON: " + responseObject.description)
  },
  failure: { (operation: AFHTTPRequestOperation!,
              error: NSError!) in
      println("Error: " + error.localizedDescription)
  })

Schauen Sie sich auch Apples Dokument an Verwenden von Swift mit Cocoa und Objective-C.

38
Jake Lin

Ich habe ein einfaches Xcode 6-Projekt geschrieben, das zeigt, wie man C++ -, Objective-C- und Swift-Code mischt:

https://github.com/romitagl/shared/tree/master/C-ObjC-Swift/Performance_Console

Insbesondere ruft das Beispiel eine Objective-C- und eine C++ - Funktion von Swift auf.

Der Schlüssel besteht darin, einen gemeinsam genutzten Header, Project-Bridging-Header.h, zu erstellen und die Objective-C-Header dort abzulegen.

Bitte laden Sie das Projekt als vollständiges Beispiel herunter.

24

Zitat aus der Dokumentation :

Jedes Objective-C-Framework (oder jede C-Bibliothek), auf das als Modul zugegriffen werden kann, kann direkt in Swift importiert werden. Dies umfasst alle Objective-C-System-Frameworks wie Foundation, UIKit und SpriteKit sowie die im Lieferumfang des Systems enthaltenen allgemeinen C-Bibliotheken. Um beispielsweise Foundation zu importieren, fügen Sie diese Importanweisung einfach oben in die Swift -Datei ein, in der Sie arbeiten:

import Foundation

Durch diesen Import sind alle Foundation-APIs - einschließlich NSDate, NSURL, NSMutableData und all ihre Methoden, Eigenschaften und Kategorien - direkt in Swift verfügbar.

21
Gergo Erdosi

Eine weitere Sache möchte ich hier hinzufügen:

Ich bin sehr dankbar für die Antwort von @ Logan. Es ist sehr hilfreich, eine Bridge-Datei und Setups zu erstellen.

Aber nach all diesen Schritten bekomme ich immer noch keinen Objective-C-Kurs in Swift.

Ich habe die Bibliothek cocoapods verwendet und in mein Projekt integriert. Welches ist pod "pop".

Wenn Sie also Objective-C-Pods in Swift verwenden, besteht möglicherweise die Möglichkeit, dass Sie die Klassen nicht in Swift bekommen oder import können.

Das Einfache, was Sie tun müssen, ist:

  1. Gehe zu <YOUR-PROJECT>-Bridging-Header Datei und
  2. Ersetzen Sie die Anweisung #import <ObjC_Framework> durch @import ObjC_Framework

Zum Beispiel: (Pop-Bibliothek)

Ersetzen

#import <pop/POP.h>

mit

@import pop;

Verwenden Sie clang import, wenn #import nicht funktioniert.

20
Kampai

Nur eine Anmerkung für alle, die versuchen, eine Objective-C-Bibliothek zu Swift hinzuzufügen: Sie sollten - ObjC in Build Settings hinzufügen. -> Linking -> Other Linker Flags .

11
david72

Nachdem Sie einen Bridging-Header erstellt haben, wechseln Sie zu Build Setting => Search for "Objective-C Bridging Header".

Direkt darunter befindet sich die Datei "" Objective-C Generated Interface Header Name ".

Importieren Sie diese Datei in Ihren View Controller.

Beispiel: In meinem Fall: "Dauble-Swift.h"

eEter image description here

8
Avijit Nagare

Klicken Sie auf das Menü Ne Datei und wählen Sie die Dateiauswahlsprache Ziel. Zu diesem Zeitpunkt wird automatisch eine "Objective-C Bridging Header" -Datei generiert, mit der ein Klassenname definiert wird.

"Objective-C Bridging Header" unter "Swift Compiler - Codegenerierung".

4
Yogesh shelke
  1. Erstellen Sie eine .h-Datei aus NewFile -> Source -> Header-Datei
  2. Speichern Sie dann den Namen der Datei Your_Target_Name-Bridging-Header.h Personen, die hier einen häufigen Fehler machen, indem sie ihren Projektnamen verwenden. Es sollte jedoch der Name des Projektziels sein, falls beide unterschiedlich sind, im Allgemeinen sind sie identisch.
  3. Suchen Sie dann in den Build-Einstellungen nach Objective-C Bridging Header flag und geben Sie die Adresse Ihrer neu erstellten Bridging-Datei ein. Klicken Sie dazu mit der rechten Maustaste auf die Datei -> im Finder anzeigen -> ziehen Sie die Datei hinein Im Textbereich wird dann die Adresse ausgefüllt.
  4. Verwenden von #import Your_Objective-C_file.h
  5. In der Datei Swift können Sie auf die ObjC-Datei zugreifen, jedoch nur in der Sprache Swift.
3
Nish

enter image description here Ich habe das Projekt auf Github hinzugefügt, das ein kleines Beispiel zum Aufrufen von Objective C-Code von Swift enthält.

ObjectiveC-Klasse von Swift aufrufen

3
CrazyPro007

Im Projekt Swift 4.2.1 in Xcode 10.1 können Sie problemlos Objective-C-Dateien hinzufügen. Führen Sie die folgenden Schritte aus, um die Objective-C-Datei mit dem Projekt Swift zu verbinden.

Schritt_01: Neues Xcode-Projekt mit Swift Sprache erstellen:

File> New> Project> objc.

Schritt_02: Fügen Sie im Projekt Swift eine neue Objective-C-Datei hinzu:

File> New> File...> macOS> Objective-C File.

Schritt_03: Wenn Sie zum ersten Mal eine neue Objective-C-Datei in das Projekt Swift einfügen, werden Sie von Xcode gefragt:

Would you like to configure an Objective-C bridging header?

enter image description here

Schritt_04: Wählen Sie die Option:

Create Bridging Header.

Schritt_05: Eine entsprechende Datei mit einem Namen wird generiert:

Objc-Bridging-Header.h.

enter image description here

Step_06: Nun müssen Sie den Pfad der Bridge-Datei im Bridge-Header einrichten. Klicken Sie im Projektnavigator auf Projekt mit dem Namen objc und wählen Sie dann:

Build Settings> Objective-C Bridging Header> Objc-Bridging-Header.h.

Schritt_07: Ziehen Sie Ihren Objc-Bridging-Header.h per Drag & Drop in dieses Feld, um einen Dateipfad zu generieren.

enter image description here

Schritt_08: Öffnen Sie Ihre Objc-Bridging-Header.h -Datei und importieren Sie die Objective-C-Datei, die Sie in Ihrer Swift -Datei verwenden möchten.

#import "SpecialObjcFile.m"

Hier ist ein Inhalt von SpecialObjcFile.m:

#import <Foundation/Foundation.h>

@interface Person: NSObject {
@public
    bool busy;
}
@property
    bool busy;
@end

Step_09: Jetzt können Sie in Ihrer Swift -Datei eine Objective-C-Klasse verwenden:

override func viewDidLoad() {
    super.viewDidLoad()
    let myObjcContent = Person()
    print(myObjcContent.busy)
}

enter image description hereenter image description here

2
ARGeo

Verwendung von Objective-C-Klassen in Swift

  1. Objective-C-Header hinzufügen .h und Implementierung .m
    Fügen Sie Ihrem Projekt die Dateien <FileName>.m und <FileName>.h hinzu

  2. Bridging-Header hinzufügen
    Wenn Sie Ihre .m-Datei hinzufügen, klicken Sie bei einer Eingabeaufforderung auf "Ja" Would you like to configure an Objective-C bridging header

  3. Klasse zum Bridging-Header hinzufügen
    In YourProject-Bridging-Header.h eine Zeile hinzufügen #import "<FileName>.h"

Verwenden von Swift Klassen in Objective-C

  1. Fügen Sie Ihrem Projekt eine <FileName>.Swift -Datei hinzu, die NSObject erweitert
  2. Importieren Sie Swift -Dateien in die ObjC-Klasse
    Fügen Sie #import "<#YourProjectName#>-Swift.h" in Ihre Objective-C-Datei ein
  3. Markiere öffentlichen Swift Code [@objc und @objcMembers]

Lesen Sie mehr hier

1
yoAlex5

Zwei-Wege-Ansatz zur Verwendung von Ziel-c Ziel-c

1

  1. Erstellen Sie die Datei bridge-header.h in Xcode Project
  2. importieren Sie die .h-Datei in die Bridge-Header-Datei
  3. Legen Sie den Pfad des Bridge-Headers in den Build-Einstellungen fest.
  4. Bereinigen Sie das Projekt

2

  1. Erstellen Sie Objective-C-Dateien im Projekt (der Pfad wird automatisch in den Build-Einstellungen für Sie festgelegt).
  2. importieren Sie die .h-Datei in die Bridge-Header-Datei

Jetzt kann es losgehenDanke

0
Sanjay Mali

Apple hat in diesem Dokument eine offizielle Anleitung bereitgestellt: Aufruf von Objective-C-Code von Swift

Hier ist der relevante Teil:

Um eine Reihe von Objective-C-Dateien in Swift Code innerhalb desselben Anwendungsziels zu importieren, verwenden Sie eine Objective-C-Überbrückungsheaderdatei um diese Dateien für Swift verfügbar zu machen . Xcode bietet an, diesen Header zu erstellen, wenn Sie einer vorhandenen Objective-C-App eine Swift-Datei oder einer vorhandenen Swift-App eine Objective-C-Datei hinzufügen.

Wenn Sie dies akzeptieren, erstellt Xcode die Überbrückungsheaderdatei zusammen mit der von Ihnen erstellten Datei und benennt sie unter Verwendung Ihres Produktmodulnamens, gefolgt von "-Bridging-Header.h". Alternativ können Sie einen Bridging-Header selbst erstellen, indem Sie Datei> Neu> Datei> [Betriebssystem]> Quelle> Header-Datei wählen.

Bearbeiten Sie den Überbrückungsheader, um Ihren Objective-C-Code Ihrem Swift-Code auszusetzen:

  1. Importieren Sie in Ihren Objective-C-Bridging-Header alle Objective-C-Header, die Sie für Swift verfügbar machen möchten.
  2. Stellen Sie in den Build-Einstellungen unter Swift Compiler - Codegenerierung sicher, dass die Build-Einstellung Objective-C-Bridging-Header einen Pfad zur Bridging-Header-Datei enthält. Der Pfad sollte relativ zu Ihrem Projekt sein, ähnlich wie Ihr Info.plist-Pfad in den Build-Einstellungen angegeben ist. In den meisten Fällen müssen Sie diese Einstellung nicht ändern.

Alle öffentlichen Objective-C-Header, die im Bridging-Header aufgeführt sind, sind für Swift sichtbar.

0
Tibin Thomas

Logans answer funktioniert einwandfrei, außer in der neuesten Version von Swift 5 tritt ein Compilerfehler auf. Hier ist der Fix für Leute, die an Swift 5 arbeiten.

Swift 5

import Foundation

class MySwiftObject : NSObject {

    var someProperty: AnyObject = "Some Initializer Val" as AnyObject

    override init() {}

    func someFunction(someArg:AnyObject) -> String {
        let returnVal = "You sent me \(someArg)"
        return returnVal
    }
}
0