Ich versuche, Swift
-Code in meine App zu integrieren. Meine App ist in Objective-C
geschrieben und ich habe eine Swift
-Klasse hinzugefügt. Ich habe alles beschrieben hier . Mein Problem ist jedoch, dass Xcode
nicht die -Swift.h
-Datei erstellt hat, sondern nur die überbrückenden Header. Also habe ich es erstellt, aber es ist eigentlich leer ... Ich kann alle meine ObjC-Klassen in Swift verwenden, aber ich kann es nicht umgekehrt machen. Ich habe meine Swift-Klasse mit @objc
markiert, aber es hat nicht geholfen. Was kann ich jetzt machen?
BEARBEITEN: Apple sagt: "Wenn Sie Swift-Code in Objective-C importieren, verlassen Sie sich auf eine Xcode-generated
-Headerdatei, um diese Dateien für Objective-C verfügbar zu machen. [...] Der Name dieses Headers ist der Name Ihres Produktmoduls, gefolgt vom Hinzufügen "-Swift.h". "
Wenn ich nun diese Datei importieren möchte, wird ein Fehler angezeigt:
//MainMenu.m
#import "myProjectModule-Swift.h" //Error: 'myProjectModule-Swift.h' file not found
@implementation MainMenu
Hier ist meine FBManager.Swift-Datei:
@objc class FBManager: NSObject {
var descr = "FBManager class"
init() {
super.init()
}
func desc(){
println(descr)
}
func getSharedGameState() -> GameState{
return GameState.sharedGameState() //OK! GameState is written in Objective-C and no error here
}
}
Ich habe ungefähr 4 Stunden damit verbracht, Swift
in meinem Xcode
Objective-C-basierten Projekt zu aktivieren. Meine "myproject-Swift.h
" -Datei wurde erfolgreich erstellt, aber meine Xcode
hat meinen Swift-classes
nicht angezeigt. Also entschied ich mich für ein neues Xcode
Objc-basiertes Projekt und schließlich fand ich die richtige Antwort! Hoffe, dieser Beitrag hilft jemandem :-)
*.Swift
-Datei (in Xcode) oder fügen Sie sie mit dem Finder hinzuObjective-C bridging header
, wenn Sie von Xcode danach gefragt werdenImplementiere deine Swift-Klasse:
import Foundation
// use @objc or @objcMembers annotation if necessary
class Foo {
//..
}
Öffnen Sie die Build-Einstellungen und überprüfen Sie diese Parameter:
YES
Parametername in eine Suchleiste kopieren und einfügen
myproject
Stellen Sie sicher, dass Ihr Produktmodulname keine Sonderzeichen enthält
YES
Sobald Sie dem Projekt eine
*.Swift
-Datei hinzugefügt haben, wird diese Eigenschaft in den Build-Einstellungen angezeigt
myproject-Swift.h
Dieser Header wird automatisch von Xcode generiert
$(SRCROOT)/myproject-Bridging-Header.h
Importieren Sie den Header der Swift-Schnittstelle in Ihre * .m-Datei
#import "myproject-Swift.h"
Achten Sie nicht auf Fehler und Warnungen.
Erstellen Sie die Headerdatei nicht selbst. Löschen Sie den von Ihnen erstellten.
Stellen Sie sicher, dass Ihre Swift-Klassen mit @objc
gekennzeichnet sind oder von einer Klasse erben, die (direkt oder indirekt) von NSObject
abgeleitet wird.
Xcode generiert die Datei nicht, wenn in Ihrem Projekt Compiler-Fehler vorliegen. Stellen Sie sicher, dass Ihr Projekt sauber erstellt wird.
Erlauben Sie Xcode seine Arbeit, fügen Sie keine Swift-Header manuell hinzu. Fügen Sie einfach @objc vor Ihrer Swift-Klasse hinzu.
@objc class YourSwiftClassName: UIViewController
Suchen Sie in Ihrer Projekteinstellung nach den folgenden Flags und ändern Sie sie in YES (sowohl Projekt als auch Ziel).
Defines Module : YES
Always Embed Swift Standard Libraries : YES
Install Objective-C Compatibility Header : YES
Bereinigen Sie dann das Projekt und erstellen Sie einmal, nachdem der Build erfolgreich abgeschlossen wurde (sollte es wahrscheinlich sein), importieren Sie die Header-Datei in Ihrer object-c-Klasse .m-Datei
#import "YourProjectName-Swift.h"
Boooom!
Vielleicht auch hilfreich für diejenigen mit einem Framework-Ziel:
Die import-Anweisung der automatisch generierten Header-Datei sieht etwas anders aus als App-Ziele. Neben den anderen in anderen Antworten genannten Dingen verwenden
#import <ProductName/ProductModuleName-Swift.h>
anstatt
#import "ProductModuleName-Swift.h"
gemäß Apples-Dokumentation zu Mix & Match für Rahmenziele.
Stellen Sie sicher, dass Ihr Projekt ein Modul definiert und Sie dem Modul einen Namen gegeben haben. Dann erstellen Sie neu und Xcode erstellt die -Swift.h
-Header-Datei und Sie können importieren.
Sie können die Moduldefinition und den Modulnamen in Ihren Projekteinstellungen festlegen.
Ich hatte das gleiche Problem und es stellte sich heraus, dass spezielle Symbole im Modulnamen durch xcode ersetzt wurden (in meinem Fall wurden Striche als Unterstriche dargestellt). Überprüfen Sie in den Projekteinstellungen "Modulname", um den Modulnamen für Ihr Projekt zu finden. Verwenden Sie danach entweder ModuleName-Swift.h
oder benennen Sie das Modul in den Einstellungen um.
Details: Objective-C-Projekt mit Swift 3-Code in Xcode 8.1
Aufgaben:
ObjcClass.h
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSInteger, ObjcEnum) {
ObjcEnumValue1,
ObjcEnumValue2,
ObjcEnumValue3
};
@interface ObjcClass : NSObject
+ (void) PrintEnumValues;
@end
ObjcClass.m
#import "ObjcClass.h"
#import "SwiftCode.h"
@implementation ObjcClass
+ (void) PrintEnumValues {
[self PrintEnumValue:SwiftEnumValue1];
[self PrintEnumValue:SwiftEnumValue2];
[self PrintEnumValue:SwiftEnumValue3];
}
+ (void) PrintEnumValue:(SwiftEnum) value {
switch (value) {
case SwiftEnumValue1:
NSLog(@"-- SwiftEnum: SwiftEnumValue1");
break;
case SwiftEnumValue2:
case SwiftEnumValue3:
NSLog(@"-- SwiftEnum: long value = %ld", (long)value);
break;
}
}
@end
In meinem Beispiel verwende ich SwiftCode.h, um Swift-Code in Objective-C zu erkennen. Diese Datei wird automatisch generiert (ich habe keine physische Kopie dieser Header-Datei in einem Projekt erstellt), und Sie können nur den Namen dieser Datei festlegen:
Wenn der Compiler den Swift-Code für die Headerdatei nicht finden kann, versuchen Sie, das Projekt zu kompilieren.
import Foundation
@objc
enum SwiftEnum: Int {
case Value1, Value2, Value3
}
@objc
class SwiftClass: NSObject {
class func PrintEnumValues() {
PrintEnumValue(.Value1)
PrintEnumValue(.Value2)
PrintEnumValue(.Value3)
}
class func PrintEnumValue(value: ObjcEnum) {
switch value {
case .Value1, .Value2:
NSLog("-- ObjcEnum: int value = \(value.rawValue)")
case .Value3:
NSLog("-- ObjcEnum: Value3")
break
}
}
}
Sie müssen eine Bridging-Header-Datei erstellen. Wenn Sie eine Swift-Datei in einem Objective-C-Projekt oder eine Objective-C-Datei in einem Swift-Projekt hinzufügen, schlägt Xcode vor, Bridging-Header zu erstellen.
Sie können den Namen der Bridging-Header-Datei hier ändern:
Überbrückungs-Header.h
#import "ObjcClass.h"
#import "SwiftCode.h"
...
[ObjcClass PrintEnumValues];
[SwiftClass PrintEnumValues];
[SwiftClass PrintEnumValue:ObjcEnumValue3];
Vollständige Integrationsschritte Objective-c und Swift wie oben beschrieben. Nun werde ich einige andere Codebeispiele schreiben.
Schnelle Klasse
import Foundation
@objc
class SwiftClass:NSObject {
private var _stringValue: String
var stringValue: String {
get {
print("SwiftClass get stringValue")
return _stringValue
}
set {
print("SwiftClass set stringValue = \(newValue)")
_stringValue = newValue
}
}
init (stringValue: String) {
print("SwiftClass init(String)")
_stringValue = stringValue
}
func printValue() {
print("SwiftClass printValue()")
print("stringValue = \(_stringValue)")
}
}
Objective-C-Code (Aufrufcode)
SwiftClass *obj = [[SwiftClass alloc] initWithStringValue: @"Hello World!"];
[obj printValue];
NSString * str = obj.stringValue;
obj.stringValue = @"HeLLo wOrLd!!!";
Ergebnis
Objective-C-Klasse (ObjcClass.h)
#import <Foundation/Foundation.h>
@interface ObjcClass : NSObject
@property NSString* stringValue;
- (instancetype) initWithStringValue:(NSString*)stringValue;
- (void) printValue;
@end
ObjcClass.m
#import "ObjcClass.h"
@interface ObjcClass()
@property NSString* strValue;
@end
@implementation ObjcClass
- (instancetype) initWithStringValue:(NSString*)stringValue {
NSLog(@"ObjcClass initWithStringValue");
_strValue = stringValue;
return self;
}
- (void) printValue {
NSLog(@"ObjcClass printValue");
NSLog(@"stringValue = %@", _strValue);
}
- (NSString*) stringValue {
NSLog(@"ObjcClass get stringValue");
return _strValue;
}
- (void) setStringValue:(NSString*)newValue {
NSLog(@"ObjcClass set stringValue = %@", newValue);
_strValue = newValue;
}
@end
Swift-Code (Anrufcode)
if let obj = ObjcClass(stringValue: "Hello World!") {
obj.printValue()
let str = obj.stringValue;
obj.stringValue = "HeLLo wOrLd!!!";
}
Ergebnis
Schnelle Erweiterung
extension UIView {
static func swiftExtensionFunc() {
NSLog("UIView swiftExtensionFunc")
}
}
Objective-C-Code (Aufrufcode)
[UIView swiftExtensionFunc];
Objective-C-Erweiterung (UIViewExtension.h)
#import <UIKit/UIKit.h>
@interface UIView (ObjcAdditions)
+ (void)objcExtensionFunc;
@end
UIViewExtension.m
@implementation UIView (ObjcAdditions)
+ (void)objcExtensionFunc {
NSLog(@"UIView objcExtensionFunc");
}
@end
Swift-Code (Anrufcode)
UIView.objcExtensionFunc()
Die Datei wird automatisch erstellt (hier geht es um Xcode 6.3.2). Sie werden es jedoch nicht sehen, da es sich in Ihrem Ordner Abgeleitete Daten befindet. Nachdem Sie Ihre Swift-Klasse mit @objc
markiert haben, kompilieren Sie sie und suchen Sie dann nach Swift.h
in Ihrem Ordner Abgeleitete Daten. Sie sollten den Swift-Header dort finden.
Ich hatte das Problem, dass Xcode meinen my-Project-Swift.h
in my_Project-Swift.h
umbenannt hat. Xcode mag keine "." "-"
usw. Symbole. Mit der oben genannten Methode können Sie den Dateinamen suchen und in eine Objective-C-Klasse importieren.
Schließen Sie einfach ein #import "myProject-Swift.h" in der .m- oder .h-Datei
PS: "myProject-Swift.h" wird im Dateiinspektor nicht angezeigt. Es wird jedoch automatisch von der App generiert.
@sig Antwort ist eine der besten, allerdings funktionierte es bei mir nicht mit dem alten Projekt (nicht neu!), ich brauchte einige Modifikationen. Nach vielen Variationen fand ich das Rezept für mich (mit XCode 7.2):
Der letzte Punkt (5) war entscheidend. Ich habe es nur auf den zweiten Abschnitt (Feld Ziele) gestellt, das Feld Projekt sollte leer bleiben: Andernfalls wurde für mich nicht die richtige "Project-Swift.h" -Datei erstellt (es enthielt keine Swift-Methoden).
Es gibt zwei Bedingungen,
Also, zu diesem Zweck musst du folgende Schritte ausführen:
Gehen Sie zu Build Settings und führen Sie die folgenden Schritte mit der Suche aus.
Bereinigen Sie anschließend Ihr Projekt und erstellen Sie es neu.
In diesem Fall schreiben Sie zuerst "@objc" vor Ihrer Klasse in die Swift-Datei.
Schreiben Sie anschließend in Ihre Objective C-Datei Folgendes:
#import "YourProjectName-Swift.h"
In diesem Fall schreiben Sie dies in Ihre Header-Datei.
#import "YourObjective-c_FileName.h"
Ich hoffe, dies wird dir helfen.
In meinem Fall, abgesehen von diesen Schritten:
Ich musste die Klasse als public setzen, um productName-Swift.h zu erstellen:
import UIKit
@objc public class TestSwift: NSObject {
func sayHello() {
print("Hi there!")
}
}
Ich hatte das gleiche Problem und schließlich schien es, als wären sie nicht an dieselben Ziele gebunden. Die ObjC-Klasse ist an Target1 und Target2 angehängt, die Swift-Klasse ist nur an Target1 angehängt und in der ObjC-Klasse nicht sichtbar.
Hoffe das hilft jemandem.
Ich habe gerade festgestellt, dass das Hinzufügen eines Verzeichnisses von Swift-Dateien zu einem Projekt nicht funktioniert. Sie müssen zuerst eine Gruppe für das Verzeichnis erstellen und dann die Swift-Dateien hinzufügen ...
Verwenden von Swift Klassen in Objective-C
Wenn Sie Code innerhalb eines App-Ziels importieren möchten (Mischen von Objective-C und Swift in einem Projekt)), sollten Sie die nächste Importzeile #import "<#YourProjectName#>-Swift.h"
Verwenden, um Swift zu Objective-C-Code [Mischen Swift und Objective-C-Code in einem Projekt]
In diesem Beitrag werde ich beschreiben, wie man Swift statische Bibliothek in Objective-C-Code importiert
Xcode Version 10.2.1
Erstellen Sie ein Bibliotheksprojekt oder ein Bibliotheksziel
File -> New -> Project... -> Cocoa Touch Static Library
//or
Project editor -> Add a Target -> Cocoa Touch Static Library
Dateien hinzufügen .Swift
Select `.Swift` file -> Select File Inspectors Tab -> Target Membership -> Select the target
//or
Project editor -> select a target -> Build Phases -> Compile Sources -> add files
Expose Swift API. Um Swifts Funktionen aus Objective-C zu nutzen [Über]
Bibliothek erstellen - ⌘ Command + B oder Product -> Build
Anmerkung: Stellen Sie sicher, dass Sie eine Bibliothek für dieselbe Prozessarchitektur wie den Clientcode erstellen.
Find generated output [Standort erstellen]
Products group -> lib<product_name>.a -> Show in Finder
Das Verzeichnis enthält
lib<product_name>.a
- eine erstellte statische Bibliothek<product_name>.swiftmodule
, Der Folgendes enthält: .swiftdoc
- docs.swiftmodule
- öffentliche Schnittstelle/DefinitionenAußerdem sollten Sie eine <product_name>-Swift.h
- Datei finden, die sich in DerivedSources
[Datei nicht gefunden]
Drag and drop
Die Binärdatei in das Xcode-Projekt [Über]
Link Library
[Undefinierte Symbole][Link vs Embed]
Project editor -> select a target -> General -> Linked Frameworks and Libraries -> add -> Add Others... -> point to `lib<product_name>.a` file
//or
Project editor -> select a target -> Build Phases -> Link Binary With Libraries -> add -> Add Others... -> point to `lib<product_name>.a` file
Addiere Library Search paths
[Bibliothek nicht gefunden für][Rekursiver Pfad]
Project editor -> select a target -> Build Settings -> Search Paths -> Library Search paths -> add path to the parent of `lib<product_name>.a` file
Addiere Header Search Paths
[Modul nicht gefunden][Rekursiver Pfad]
Project editor -> select a target -> Build Settings -> Search Paths -> Header Search Paths -> add path to generated `<product_name>-Swift.h` file
Fügen Sie dem Objective-C-Projekt ein leeres .Swift file
Hinzu. [Undefinierte Symbole] Wenn Sie Xcode fragen, klicken Sie auf Create Bridging Header
(Es wird module_name-Bridging-Header.h
Erstellt) und richten Sie einen Pfad zu dieser Datei in ein
Project editor -> select a target -> Build Settings -> Swift Compiler - General -> Objective-C Bridging Header
Modul in den Objective-C-Clientcode importieren [Datei nicht gefunden] [Modulname]
#import "module_name-Swift.h"
Für Swift 5:
@objc
hinzupublic
hinzuNSObject
erbenFügen Sie #import "MyProject-Swift.h"
in Ihre Objective-C-Datei ein
@objc
public class MyClass: NSObject {
@objc
public func myMethod() {
}
}
Ich hatte Probleme, dass ich Klassen zu meinem Objective-C-Bridging-Header hinzufügen würde. In den importierten Objective-C-Headern wurde versucht, den Swift-Header zu importieren. Das hat mir nicht gefallen.
In all meinen Objective-c-Klassen, die Swift verwenden, aber auch überbrückt sind, bestand der Schlüssel darin, sicherzustellen, dass Sie in den Kopfzeilen Vorwärtsklassendeklarationen verwenden und dann die Datei "* -Swift.h" in die Datei .m importieren.
Ich musste keine Einstellungen im Build ändern oder @obj zur Klasse hinzufügen.
Ich musste nur einen Bridge-Header erstellen, der automatisch erstellt wurde, als ich Swift-Klassen in Objective-c-Projekten erstellte. Und dann musste ich einfach tun
Wenn Sie dem Projekt neue Swift Dateien hinzufügen, stellen Sie bitte sicher, dass Sie sie zu korrekten Zielen hinzufügen. Stellen Sie sicher, dass jede Swift -Datei, die Sie verwenden möchten, die NSObject-Klasse erbt und mit @ObjCMembers annotiert. Ändern Sie in den Build-Einstellungen unter der Option ALWAYS_EMBED_Swift_STANDARD_LIBRARIES auf YES. Wechseln Sie in den Build-Einstellungen unter der Option DEFINES_MODULE zu YES.
mein Problem war, dass ich nach dem Erstellen der Bridge-Datei durch xcode stecken blieb, aber ich bekam immer noch einen Fehler im Header-Dateinamen MYPROJECTNAME-Swift.h
1.Ich checke im Terminal ein und suche nach allen automatisch erstellten Swift-Bridge-Dateien:
find ~/library/Developer/Xcode/DerivedData/ -name "*-Swift.h"|xargs basename|sort -
sie sehen, welcher Xcode erstellt wurde.
Mein Problem war, dass die automatische Generierung der Datei -Swift.h eine Unterklasse von CustomDebugStringConvertible nicht verstehen konnte. Ich habe die Klasse geändert, stattdessen eine Unterklasse von NSObject zu sein. Danach hat die -Swift.h-Datei die Klasse jetzt korrekt eingefügt.
nun, nachdem ich alle Kommentare gelesen und versucht und gelesen und erneut versucht habe, habe ich es geschafft, Swift-Klassen in mein Big obj-c-Projekt aufzunehmen. Also, vielen Dank für all die Hilfe. Ich wollte einen Tipp teilen hat mir geholfen, den Prozess besser zu verstehen. In der Klasse .m ging ich zur Importzeile des Swift-Zielnamens #import "myTargetName-Swift.h" und klickte auf den Schlüssel:
befehl + Mausklick -> Zur Definition springen
Dort können Sie die gesamte Übersetzung von Swift in obj-c sehen. Dort finden Sie die verschiedenen Funktionen, die in obj-c erneut deklariert wurden. Hoffen Sie, dass dieser Tipp Ihnen so sehr hilft, wie er mir geholfen hat.
Ich habe den gleichen Fehler: myProjectModule-Swift.h
-Datei nicht gefunden ", aber in meinem Fall lag der wahre Grund in einem falschen Implementierungsziel: " Swift
ist unter OS X vor 10.9 nicht verfügbar. Setzen Sie MACOSX_DEPLOYMENT_TARGET
auf 10.9 oder höher (derzeit ist es '10 .7 ') " Wenn ich das Implementierungsziel auf 10.9 geändert habe, wurde das Projekt erfolgreich kompiliert.