J'essaie d'intégrer le code Swift
dans mon application. Mon application est écrite en Objective-C
et j'ai ajouté une classe Swift
. J'ai tout fait décrit ici . Mais mon problème est que Xcode
n'a pas créé le fichier -Swift.h
, mais uniquement les en-têtes de pontage. Donc je l’ai créé, mais c’est en fait vide… .. Je peux utiliser toutes mes classes ObjC dans Swift, mais je ne peux pas le faire inversement. J'ai marqué ma classe Swift avec @objc
mais cela n'a pas aidé. Que puis-je faire maintenant?
EDIT: Apple déclare: "Lorsque vous importez du code Swift dans Objective-C, vous comptez sur un fichier d’entête Xcode-generated
pour exposer ces fichiers à Objective-C. "-Swift.h". "
Maintenant, quand je veux importer ce fichier, cela donne une erreur:
//MainMenu.m
#import "myProjectModule-Swift.h" //Error: 'myProjectModule-Swift.h' file not found
@implementation MainMenu
Voici mon fichier FBManager.Swift:
@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
}
}
J'ai passé environ 4 heures à essayer d'activer Swift
dans mon projet Xcode
basé sur Objective-C. Mon fichier "myproject-Swift.h
" a été créé avec succès, mais ma Xcode
n'a pas vu mon Swift-classes
. J'ai donc décidé de créer un nouveau projet Xcode
basé sur Objc et j'ai finalement trouvé la bonne réponse! J'espère que ce post aidera quelqu'un :-)
*.Swift
(dans Xcode) ou ajoutez-le à l'aide du FinderObjective-C bridging header
quand Xcode vous le demanderaImplémentez votre classe Swift:
import Foundation
// use @objc or @objcMembers annotation if necessary
class Foo {
//..
}
Ouvrez les paramètres de construction et vérifiez ces paramètres:
YES
Copier et coller le nom du paramètre dans une barre de recherche
myproject
Assurez-vous que votre nom de module de produit ne contient aucun caractère spécial
YES
Une fois que vous avez ajouté le fichier
*.Swift
au projet, cette propriété apparaît dans les paramètres de construction.
myproject-Swift.h
.____.Cet en-tête est généré automatiquement par Xcode.
$(SRCROOT)/myproject-Bridging-Header.h
Importer l'en-tête d'interface Swift dans votre fichier * .m
#import "myproject-Swift.h"
Ne faites pas attention aux erreurs et aux avertissements.
Ne créez pas le fichier d'en-tête vous-même. Supprimez celui que vous avez créé.
Assurez-vous que vos classes Swift portent la balise @objc
ou héritent d'une classe dérivée (directement ou indirectement) de NSObject
.
Xcode ne générera pas le fichier si vous rencontrez des erreurs de compilation dans votre projet. Assurez-vous que votre projet est construit correctement.
Autoriser Xcode à faire son travail, ne pas ajouter/créer d'en-tête Swift manuellement. Ajoutez simplement @objc avant votre classe Swift ex.
@objc class YourSwiftClassName: UIViewController
Dans le cadre de votre projet, recherchez les indicateurs ci-dessous et remplacez-le par OUI (projet et cible).
Defines Module : YES
Always Embed Swift Standard Libraries : YES
Install Objective-C Compatibility Header : YES
Nettoyez ensuite le projet et générez-le une fois. Une fois la construction réussie (probablement), importez-le sous le fichier d'en-tête de votre fichier .m
#import "YourProjectName-Swift.h"
Boooom!
Aussi probablement utile pour ceux d'entre vous avec une cible Framework:
L'instruction import du fichier d'en-tête généré automatiquement ressemble un peu différent des cibles de l'application. En plus des autres choses mentionnées dans d’autres réponses, utilisez
#import <ProductName/ProductModuleName-Swift.h>
au lieu de
#import "ProductModuleName-Swift.h"
conformément à la documentation Apples sur Mix & Match pour les objectifs-cadres.
Assurez-vous que votre projet définit un module et que vous en avez donné un nom. Ensuite, reconstruisez, et Xcode créera le fichier d’en-tête -Swift.h
et vous pourrez importer.
Vous pouvez définir la définition et le nom du module dans les paramètres de votre projet.
J'ai eu le même problème et il s'est avéré que des symboles spéciaux dans le nom du module sont remplacés par xcode (dans mon cas, les tirets étaient des traits de soulignement). Dans les paramètres du projet, cochez "nom du module" pour trouver le nom du module pour votre projet. Après cela, utilisez ModuleName-Swift.h
ou renommez le module dans les paramètres.
Détails: Projet Objective-C avec code Swift 3 dans Xcode 8.1
Les tâches:
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
Dans mon exemple, j'utilise SwiftCode.h pour détecter le code Swift dans Objective-C. Ce fichier génère automatiquement (je n'ai pas créé de copie physique de ce fichier d'en-tête dans un projet), et vous pouvez uniquement définir le nom de ce fichier:
Si le compilateur ne trouve pas votre code Swift dans le fichier d’en-tête, essayez de compiler le projet.
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
}
}
}
Vous devez créer un fichier d'en-tête de pontage. Lorsque vous ajoutez un fichier Swift dans un projet Objective-C ou un fichier Objective-C dans un projet Swift, Xcode vous suggère de créer un en-tête de pontage.
Vous pouvez modifier le nom du fichier d'en-tête de pontage ici:
Bridging-Header.h
#import "ObjcClass.h"
#import "SwiftCode.h"
...
[ObjcClass PrintEnumValues];
[SwiftClass PrintEnumValues];
[SwiftClass PrintEnumValue:ObjcEnumValue3];
Etapes d'intégration complète Objective-c et Swift décrites ci-dessus. Maintenant, je vais écrire d'autres exemples de code.
Classe rapide
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)")
}
}
Code Objective-C (code d'appel)
SwiftClass *obj = [[SwiftClass alloc] initWithStringValue: @"Hello World!"];
[obj printValue];
NSString * str = obj.stringValue;
obj.stringValue = @"HeLLo wOrLd!!!";
Résultat
Classe Objective-C (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
Code Swift (code d'appel)
if let obj = ObjcClass(stringValue: "Hello World!") {
obj.printValue()
let str = obj.stringValue;
obj.stringValue = "HeLLo wOrLd!!!";
}
Résultat
Extension rapide
extension UIView {
static func swiftExtensionFunc() {
NSLog("UIView swiftExtensionFunc")
}
}
Code Objective-C (code d'appel)
[UIView swiftExtensionFunc];
Extension Objective-C (UIViewExtension.h)
#import <UIKit/UIKit.h>
@interface UIView (ObjcAdditions)
+ (void)objcExtensionFunc;
@end
UIViewExtension.m
@implementation UIView (ObjcAdditions)
+ (void)objcExtensionFunc {
NSLog(@"UIView objcExtensionFunc");
}
@end
Code Swift (code d'appel)
UIView.objcExtensionFunc()
Le fichier est créé automatiquement (en parlant de Xcode 6.3.2 ici). Mais vous ne le verrez pas, car il se trouve dans votre dossier Derived Data. Après avoir marqué votre classe Swift avec @objc
, compilez-le, puis recherchez Swift.h
dans votre dossier Derived Data. Vous devriez trouver l'en-tête Swift ici.
Le problème est que Xcode a renommé mon my-Project-Swift.h
en my_Project-Swift.h
. Xcode n’aime pas les symboles "." "-"
etc. Avec la méthode ci-dessus, vous pouvez trouver le nom du fichier et l'importer dans une classe Objective-C.
Il suffit d'inclure #import "myProject-Swift.h" dans un fichier .m ou .h
P.S Vous ne trouverez pas "myProject-Swift.h" dans l'inspecteur de fichiers, il est masqué. Mais il est généré automatiquement par l'application.
@sig answer est l'un des meilleurs, cependant cela ne fonctionnait pas pour moi avec l'ancien projet (pas nouveau!), j'avais besoin de quelques modifications. Après de nombreuses variantes, j'ai trouvé la recette (en utilisant XCode 7.2):
Le dernier point (5) était crucial. Je le mets uniquement sur la deuxième section (champ Cibles), le champ Projet doit rester vide: Sinon, il ne m'a pas généré le fichier "Project-Swift.h" correct (il n'incluait pas les méthodes Swift).
Il y a deux conditions,
Alors, pour cela, vous devez suivre ces étapes:
Allez dans Configurer les paramètres et effectuez les étapes ci-dessous avec la recherche,
Après cela, nettoyez et reconstruisez votre projet.
Dans ce cas, écrivez d'abord "@objc" avant votre classe dans le fichier Swift.
Après cela, dans votre fichier Objective C, écrivez ceci,
#import "YourProjectName-Swift.h"
Dans ce cas, dans votre fichier d'en-tête, écrivez ceci,
#import "YourObjective-c_FileName.h"
J'espère que cela t'aidera.
Dans mon cas, en dehors de ces étapes:
J'ai eu besoin de mettre la classe comme public pour créer productName-Swift.h fichier:
import UIKit
@objc public class TestSwift: NSObject {
func sayHello() {
print("Hi there!")
}
}
J'ai eu le même problème et finalement, il est apparu qu'ils n'étaient pas attachés aux mêmes objectifs. La classe ObjC est attachée à Target1 et Target2, la classe Swift n'est attachée qu'à Target1 et n'est pas visible à l'intérieur de la classe ObjC.
J'espère que ça aide quelqu'un.
Je viens de découvrir que l'ajout d'un répertoire de fichiers Swift à un projet ne fonctionnera pas. Vous devez d'abord créer un groupe pour le répertoire, puis ajouter les fichiers Swift ...
Utilisation de Swift Classes en Objective-C
Si vous envisagez d'importer du code dans une cible d'application (en mélangeant Objective-C et Swift dans un projet), vous devez utiliser la ligne d'importation suivante #import "<#YourProjectName#>-Swift.h"
pour afficher le code Swift. au code Objective-C [Mélange Swift et code Objective-C dans un projet]
Dans ce post, je vais décrire comment importer Swift bibliothèque statique en code Objective-C
Xcode version 10.2.1
Créer un projet de bibliothèque ou créer une cible de bibliothèque
File -> New -> Project... -> Cocoa Touch Static Library
//or
Project editor -> Add a Target -> Cocoa Touch Static Library
Ajouter des fichiers .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
Exposer Swift API. Pour utiliser les fonctions de Swift depuis Objective-C [À propos]
Construire une bibliothèque - ⌘ Command + B ou Product -> Build
Remarque: assurez-vous de créer la bibliothèque pour la même architecture de processus que le code client.
Trouver la sortie générée [Lieu de construction]
Products group -> lib<product_name>.a -> Show in Finder
Le répertoire comprend
lib<product_name>.a
- une bibliothèque statique construite<product_name>.swiftmodule
dossier qui comprend: .swiftdoc
- docs.swiftmodule
- interface publique/définitionsAussi, vous devriez trouver un fichier <product_name>-Swift.h
qui devrait être situé dans DerivedSources
[Fichier non trouvé]
Drag and drop
le binaire dans le projet Xcode [À propos]
Link Library
[Symboles non définis][Lien vs Intégrer]
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
Ajouter Library Search paths
[Bibliothèque introuvable pour][Chemin récursif]
Project editor -> select a target -> Build Settings -> Search Paths -> Library Search paths -> add path to the parent of `lib<product_name>.a` file
Ajouter Header Search Paths
[Module non trouvé][Chemin récursif]
Project editor -> select a target -> Build Settings -> Search Paths -> Header Search Paths -> add path to generated `<product_name>-Swift.h` file
Ajoutez .Swift file
vide au projet Objective-C . [Symboles non définis] Lorsque Xcode demande, appuyez sur Create Bridging Header
(il créera module_name-Bridging-Header.h
) et définissez un chemin vers ce fichier dans
Project editor -> select a target -> Build Settings -> Swift Compiler - General -> Objective-C Bridging Header
Module d'importation dans le code client Objective-C [Fichier non trouvé] [nom_module]
#import "module_name-Swift.h"
Pour Swift 5:
@objc
à votre classe et à vos méthodespublic
à votre classe et à vos méthodesNSObject
Mettez #import "MyProject-Swift.h"
dans votre fichier Objective-C
@objc
public class MyClass: NSObject {
@objc
public func myMethod() {
}
}
J'avais des problèmes en ce sens que j'ajouterais des classes à mon en-tête de transition objective-c, et dans les en-têtes d'objectif-c importés, ils essayaient d'importer l'en-tête Swift. Ça n'a pas aimé ça.
Ainsi, dans toutes mes classes objective-c qui utilisent Swift, mais sont également pontées, la clé était de vous assurer que vous utilisez les déclarations de classe en aval dans les en-têtes, puis importez le fichier "* -Swift.h" dans le fichier .m.
Je n'ai pas eu à modifier les paramètres de la construction ni à ajouter @obj à la classe.
Tout ce que j'avais à faire était de créer un en-tête de pont qui a été créé automatiquement lorsque j'ai créé des classes Swift dans un projet Objective-c. Et puis je devais juste faire
Lorsque vous ajoutez de nouveaux fichiers Swift au projet, assurez-vous de les ajouter aux cibles appropriées. Assurez-vous que tous les fichiers Swift que vous allez utiliser héritent de la classe NSObject et sont annotés avec @ObjCMembers Passez à YES dans les paramètres de construction sous l'option ALWAYS_EMBED_Swift_STANDARD_LIBRARIES. Passez à OUI dans les paramètres de construction de l'option DEFINES_MODULE.
mon problème était que je me suis retrouvé coincé après que xcode ait créé le fichier bridge, mais j'ai toujours une erreur dans le nom du fichier d'en-tête MYPROJECTNAME-Swift.h
1.J'enregistre dans le terminal et recherche tous les fichiers de pont Swift créés automatiquement:
find ~/library/Developer/Xcode/DerivedData/ -name "*-Swift.h"|xargs basename|sort -
vous voyez quel xcode créé.
Mon problème était que la génération automatique du fichier -Swift.h n'était pas capable de comprendre une sous-classe de CustomDebugStringConvertible. J'ai changé la classe pour être une sous-classe de NSObject à la place. Après cela, le fichier -Swift.h incluait maintenant correctement la classe.
eh bien, après avoir lu tous les commentaires et essayé encore et encore, j’ai réussi à inclure des classes Swift dans mon projet Big obj-c . Alors, merci pour toute l’aide . Je voulais partager un conseil qui m'a aidé à mieux comprendre le processus . Dans la classe .m, est allé à la ligne d'importation du nom de la cible Swift #import "myTargetName-Swift.h" et a cliqué sur la clé:
commande + clic de souris -> Aller à la définition
Là, vous pouvez voir toute la traduction de Swift en obj-c et vous y trouverez les différentes fonctions déclarées à nouveau dans obj-c . J'espère que ce conseil vous aidera autant qu'il m'a aidé.
J'ai la même erreur: myProjectModule-Swift.h
fichier non trouvé ", mais dans mon cas, la vraie raison était dans la cible de déploiement incorrecte: " Swift
n'est pas disponible sur OS X antérieure à 10.9; veuillez définir MACOSX_DEPLOYMENT_TARGET
sur 10.9 ou ultérieur (actuellement, il s'agit de '10 .7 ') " Ainsi, lorsque j'ai modifié la cible de déploiement en 10.9 - le projet a été compilé avec succès.