Ich versuche, ohne Erfolg an einem gemischten Swift- und ObjectiveC-Projekt zu arbeiten.
Mein Projekt besteht aus 6 Zielen:
Ich konnte eine Swift-Klasse mit einer Zielmitgliedschaft (App) hinzufügen und verwende ObjectiveC-Code, der aus dem App-Bridging-Header.h übergeben wird. Das Paradigma "ObjectiveC in Swift-Code" funktioniert wie ein Zauber .
Stattdessen kämpfe ich mit dem Paradigma "Swift into ObjectiveC Code". In dem speziellen Fall muss ich eine neue Swift-Klasse in einer ObjectiveC .m-Datei verwenden, die Mitglied von vier Zielen ist.
Was ich bisher gemacht habe, ist Folgendes:
Ich habe den Mix and Match-Leitfaden von Apple befolgt und viele SO Threads, einschließlich dieses , das anscheinend das gleiche Problem wie ich zu lösen scheint, aber es funktioniert nicht.
Habe auch das und das gesehen, aber es hat nicht funktioniert.
Ich habe auch versucht, abgeleitete Daten zu löschen und das gesamte Projekt mehrmals ohne Erfolg zu bereinigen.
EDIT 1: Weitere Details
Dies ist die Deklaration meines Swift-Klassenimports RealmSwift
@objc class MyClass: Object {}
Dies ist der Ausschnitt aus der Verwendung der Swift-Klasse in ObjectiveC
MyClass *app = [[MyClass alloc] init];
Wenn ich die Verwendung von #import ...- Swift.h vermeide, wird in der Erstellung nicht angegeben, dass ich eine nicht deklarierte IDenfier "MyClass" verwende, und dies ist einwandfrei.
Wenn ich #import ...- Swift.h-Dateien verwende, heißt es, dass Modul X Modul Y nicht finden kann und so weiter.
EDIT 2: Swift-Modulname
Beim Betrachten der Swift_OBJC_INTERFACE_HEADER_NAME -Eigenschaft jedes Ziels habe ich festgestellt, dass es mit dieser Syntax erstellt wurde $ (Swift_MODULE_NAME) -Swift.h muss ich Swift_MODULE_NAME ändern bis MODULE_NAME ?
EDIT 3: Importe
Dies ist die Gruppe von Importen für Swift-Header in der ObjectiveC-Datei .m. Ich verwende die Modulnamen, die in den relativen Eigenschaften der Build-Einstellungen angegeben sind. Beachten Sie, dass ein Benutzer das Zeichen "_" hat, da das WatchKit-Erweiterungsziel ein Leerzeichen im Zielnamen enthält.
#import "ProjectName_App-Swift.h"
#import "ProjectName_Core-Swift.h"
#import "ProjectName_Summary-Swift.h"
#import "ProjectName_WatchKit_Extension-Swift.h"
EDIT 4: Cross Visibility von -Swift.h-Dateien
Ich habe Folgendes versucht:
Wenn die Swift-Klasse für mehrere Ziele definiert ist und die ObjectiveC-Datei von diesen mehreren Zielen verwendet wird, funktioniert sie nicht. Die Erstellungsfehler lauten wie folgt: Ziel X -> Datei "ProjectName_TargetY-Swift.h" nicht gefunden. Scheint, als ob ein Ziel andere Ziele nicht sehen kann -Swift.h-Dateien.
Was mache ich falsch? Danke für Ihre Hilfe
Die Annahme, die ich in Edit 4 gemacht habe, erwies sich als die richtige. Wenn ein Projekt mehrere Ziele hat, können die "-Swift.h" -Dateien nicht alle in einer .m ObjectiveC-Datei importiert werden.
Es gibt also eine Lösung, die angenommen werden muss, und es ist die Build-Einstellung Swift_OBJC_INTERFACE_HEADER_NAME zu ändern und für verschiedene Ziele gleich zu machen. Dazu muss die Anweisung, die diese Eigenschaft generiert, aus $ (Swift_MODULE_NAME) geändert werden ) -Swift.h an $ (PROJECT_NAME) -Swift.h wie erklärt hier
Es ist auch möglich, die Einstellung des Produktmodulnamens in den Build-Einstellungen für alle Module gleich einzustellen (ich habe sie auf $ (PROJECT_NAME) gesetzt), so dass die generierte Datei -Swift.h in allen Modulen den gleichen Namen hat . Dadurch müssen keine Präprozessor-Makros hinzugefügt/geprüft werden.
Bereinigen Sie den Build-Ordner, indem Sie die Alt-Taste drücken und das Produktmenü aufrufen. Da der Name des Headers jetzt von Zielen geteilt wird, kann er einmal in die ObjectiveC-Datei von .m importiert werden, und alle Ziele können von Swift-Klassen profitieren.
Wenn nach dem Erstellen immer noch der Fehler angezeigt wird, stellen Sie sicher, dass der Header von XCode aus erreichbar ist, indem Sie auf den Namen der Befehlszeile klicken. Es sollte eine Datei öffnen, die folgenden Code enthält:
Swift_CLASS("_TtC27ProjectName_Summary11MyClass")
@interface MyClass : NSObject
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end
Wenn Sie sicherstellen müssen, dass diese Header generiert werden, öffnen Sie ein Terminal und verwenden Sie diesen Befehl
find ~/Library/Developer/Xcode/DerivedData -name "*Swift.h"
Für jedes Ziel sollte ein Header angezeigt werden
Ein anderes Problem, das mir nach diesen Änderungen passierte, ist, dass es Fehler in ObjectiveC-Code gab, den ich nicht anrief. Das Problem war auf die Position des Imports zurückzuführen, wie hier :
Genau dort, wo Sie am oberen Rand einer .m-Datei den importierten versteckten Überbrückungsheader importieren, kann dies einen Unterschied machen. Das übliche Anzeichen für Probleme ist, dass Sie einen Kompilierungsfehler mit dem Namen "Unknown type name" erhalten, wobei der unbekannte Typ eine in Objective-C deklarierte Klasse ist. Die Lösung besteht darin, die .h-Datei mit der Deklaration für den unbekannten Typ in Ihren Objective-C-Dateien zu importieren, bevor Sie den versteckten Bridging-Header importieren. Dies zu tun kann ein Ärgernis sein, insbesondere wenn die betreffende Objective-C-Datei über diese Klasse nicht informiert werden muss, das Problem jedoch gelöst wird und die Kompilierung fortgesetzt werden kann.
Am Ende wird der Code kompiliert und läuft auf Gerät und Simulator!
Die Lösung für mich war, den generierten Swift-Header über die <>
-Syntax zu importieren:
#import <OtherTargetWithSwiftClass/OtherTargetWithSwiftClass-Swift.h>
Dies ist keine Lösung für die Frage, aber da viele auf dieser Seite landen und nach dem Problem suchen, dass die <ModuleName>-Swift.h
-Datei nicht gefunden wird (genau wie ich), möchte ich einen weiteren möglichen Grund hinzufügen:
Wenn in einer Swift-Datei ein Compiler-Problem auftritt, wird der Header möglicherweise nicht von Xcode generiert und daher fehlt die Datei.
Zumindest in meinem Fall war der <ModuleName>-Swift.h not found
weg, nachdem ich den Kompilierungsfehler in der Swift-Datei behoben hatte.
Ich hatte ein ähnliches Problem und verbrachte fast einen ganzen Tag damit, das Problem herauszufinden, während ich den Anregungen anderer Entwickler von StackOverflow und einigen anderen Quellen folgte.
Ich habe ein Upgrade von Xcode 7.3.1 auf Xcode 8.2.1 und Swift 2.2 auf Swift 3.0.1 durchgeführt.
In meinem Fall habe ich herausgefunden, dass die PROJECT_NAME-Swift.h
-Datei nicht erstellt wurde:
~/Library/Developer/Xcode/DerivedData/PRODUCT-NAME-hdkrxixrxbiorwesffpqvefxsrzl/Build/Intermediates/PRODUCT-NAME.build/Debug/PRODUCT-NAME.build/Objects-normal/x86_64/PRODUCT-NAME-Swift.h.
Ich vermute, es versucht irgendwie, auf diese Header-Datei vom obigen Pfad und dem Fehler zu verweisen. Ich habe es manuell kopiert. Nach diesem Vorgang wurde kein sauberer Build ausgeführt .. Dies behebte mein Problem und die Swift-Header-Datei wurde für die weitere Kompilierung und Erstellung erstellt.
In meinem Fall habe ich einen Arbeitsbereich mit einem iOS-App-Teilprojekt, einem Framework-Teilprojekt und einem CocoaPods Pods-Teilprojekt. Der Fehler "ModuleName-Swift.h-Datei wurde nicht gefunden" ist in meinem Framework-Teilprojekt aufgetreten, da die Datei noch nicht vom Pods-Unterprojekt erstellt wurde.
Ich bin nicht sicher, ob es eine Möglichkeit gibt, Xcode über Abhängigkeiten zwischen Unterprojekten zu informieren, aber ich habe sie einfach im linken Projektnavigator neu geordnet:
Funktionierte danach gut!
Für meinen Fall läuft es einwandfrei in Xcode 8 aber Dateien mit
#import "Project-Swift.h"
hat fehlende Importe, wie von LucioB beschrieben
Mit Xcode 9 werden diese Fehler beseitigt