web-dev-qa-db-fra.com

Swift vers l'en-tête Objective-C non créé dans Xcode 6

J'ai récemment travaillé pour ajouter Swift à un projet existant, pour pouvoir l'essayer de manière réaliste.

Lors de l'ajout d'un fichier source Swift au projet, je n'ai aucun problème à obtenir "l'en-tête de pontage", c'est-à-dire Objective-C to Swift.

Mais le fichier d'en-tête *-Swift.h censé exposer les classes Swift marquées @objc ou les sous-classes des classes ObjC est nulle part être trouvé :-(

Je ne vois aucune instruction spécifique sur la façon d'utiliser l'utilisation de ma nouvelle sous-classe, écrite en Swift, dans le code de mon application principale (qui est toujours Objective-C).

L'application que je suis développeur principal a une base de code assez grande (70 000 lignes), il est donc hors de question de la transformer en une seule fois.

239
David Kristensen

Maintenant ça marche.

  1. Le projet doit avoir un nom de module de produit qui pas inclut des espaces.
  2. Définit le module doit être défini sur Oui dans les paramètres de construction, sous Conditionnement.

Enfin fonctionne. Merci à tous pour l'aide :-)

162
David Kristensen

J'ai eu un problème similaire et j'ai constaté que vous ne pouvez ajouter que

#import “ProductModuleName-Swift.h”

aux fichiers obj-c .m, pas aux fichiers .h pour que l'en-tête de parapluie soit trouvé

122
macduff

J'ai trouvé que je devais corriger les erreurs de compilation all avant de générer le fichier.

Le problème pour moi était que c'était un problème poulet/oeuf, en ce sens que je ne voyais aucune erreur de construction avant d'avoir commenté la déclaration #import:

//#import "ProductModuleName-Swift.h"

qui a révélé un tas d'autres erreurs dans mon code Swift.

Une fois que j'ai corrigé ces nouvelles erreurs et obtenu la construction du code source avec succès, j'ai annulé le commentaire du #import et du bingo! L'en-tête a été créé et importe correctement :)

58
petehare

Si vous êtes comme moi, le nom de l'en-tête est probablement erroné. Après avoir frappé ma tête pendant un moment, j'ai cherché le fichier dans DerivedData et, bien sûr, il est là. Sur ma configuration (en utilisant le dossier de données dérivé standard, je crois):

cd ~/Library/Developer/Xcode/DerivedData
find * -iname '*Swift.h'

Je le trouverai. Si rien dans ce dossier ne correspond, Xcode ne le génère pas.

J'utilise Xcode Version 6.2 (6C86e)

42
Lou Zell

Si le nom de votre module de projet contient des espaces, vous devez les remplacer par un trait de soulignement.

Par exemple, si votre nom de projet est "Mon projet", vous utiliserez:

#import "My_Project-Swift.h"

42
JohnMorrison

* La seule chose importante est: *

utiliser le "Nom du module de produit" défini dans la cible, suivi de -Swift.h

#import <Product Module Name>-Swift.h

// in each ObjectiveC .m file having to use Swift classes
// no matter in which Swift files these classes sit.

Peu importe si le paramètre "Defines Module" est défini sur Oui ou Non ou si le "Nom du module de produit" n'est pas défini.

Rappel: _ Les classes Swift doivent dériver de NSObject ou avoir été étiquetées avec l'attribut @objc pour être exposées à ObjectiveC/Foundation || Cacao ...

31
Luc-Olivier

Je voulais ajouter une raison de plus pour laquelle vous pourriez trouver un problème avec ceci: je créais un cadre qui mélangeait le code Swift et le code Objective-C. Je n'ai pas été en mesure d'importer les classes Swift en dehors du cadre. J'ai vérifié le fichier -Swift.h. Ce fichier était en cours de génération, mais était vide.

Le problème s’est révélé être très, très simple: je n’avais déclaré aucune de mes Swift classes publiques! Dès que j'ai ajouté le mot clé public aux classes, j'ai pu les utiliser à partir de classes à l'intérieur et à l'extérieur du cadre.

Il convient également de noter que dans le cadre (dans les fichiers .m uniquement comme une autre réponse le mentionne), je devais importer le fichier -Swift.h en tant que:

#import <FrameworkName/FrameworkName-Swift.h>

J'ai eu le même problème. On dirait que vous devez ajuster les paramètres (Définit le module et le nom du module du produit) avant vous ajoutez votre premier fichier Swift.

Si vous le faites ensuite, le fichier "* -Swift.h" ne sera pas généré pour ce projet, même si vous ajoutez d'autres fichiers Swift ou supprimez le fichier Swift et en créez un nouveau. .

14
user3540830

Voici une autre variante du nom de module-Swift.h non généré.

J'ai décidé d'inclure IOS Charts dans mon projet, mais je ne voulais pas mélanger les sources dans le même répertoire. J'ai donc placé le dossier Charts Project à côté du dossier de projet de mon code. J'ai fait glisser le projet Graphiques dans la barre de navigation de mon projet et inclus le cadre dans la liste des Fichiers binaires incorporés de la cible de mon projet dans Le ​​contenu incorporé contient Swift Code == passez à yes dans mon projet Paramètres de construction onglet dans la section Options de construction.

Le fichier moduleName-Swift.h de mon projet ne générerait jamais, quels que soient les autres commutateurs ou paramètres suggérés ici. Enfin, en utilisant la méthode de Lou Z consistant à rechercher les fichiers -Swift.h, j'ai constaté qu'un fichier Charts-Swift.h était en cours de génération dans le répertoire de construction xcode de mon projet dans Charts.framework/Headers /

La solution pour utiliser le package ios-charts Swift de Daniel Gindi sans inclure le code dans le répertoire source de mon projet consistait à ajouter:

#import "Charts/Charts-Swift.h"

Aux modules de cartographie des données de mon projet.

12
gjpc

Le nom du fichier est toujours précédé de votre nom Target. Il s’agit du nom de produit mais c’est pratiquement le nom de la cible. Donc, si vous voulez construire pour une nouvelle cible, soyez prêt à attendre le fichier that_target-Swift.h.

Une façon de gérer cela est

  1. Ajoutez un préprocesseur pour chaque cible, le nom de votre cible elle-même (sans espaces). Ex. MY_TARGET=1. Ajoutez ceci dans Paramètres du projet-> Construire les paramètres-> Macros de préprocesseur pour chacune de vos cibles.
  2. Si vous utilisez un fichier PCH,

Ajouter ces lignes dans le fichier PCH

#if MY_TARGET==1
#include "My_Target-Swift.h"
#Elif THAT_TARGET==1
#include "That_Target-Swift.h" 
#endif

L'avantage d'utiliser le fichier PCH est que vous n'avez pas à inclure les en-têtes partout.

  1. Si vous n'utilisez pas de fichier PCH, ajoutez simplement ces mêmes lignes dans un en-tête unique et incluez cet en-tête chaque fois que vous devez utiliser les classes Swift.

Cela devrait bien fonctionner.

12
Deepak G M

Permettez-moi de partager mes expériences en essayant d'utiliser Swift dans un ancien projet objc. Je n'avais pas besoin de régler Defines module sur YES.

Dans mon cas, je devais manuellement m'assurer qu'il y avait un en-tête de pontage d'objet. Seul le nom d'en-tête d'interface généré était présent dans mes paramètres de construction.

Missing bridging header

Cela a entraîné la création d'un fichier MyApp-Swift.h, mais sans aucune trace de mes classes Swift.

La documentation Apple indique que vous serez invité à créer un en-tête de pontage lors de l'ajout de votre premier fichier Swift. Eh bien, je n'étais pas. J'ai ajouté manuellement un fichier MyApp-Bridging-header.h et l'ai pointé dans le champ "En-tête de pontage Objective-C". Cela a rendu mon fichier MyApp-Swift.h plus peuplé avec mes classes Swift.

Docs: Importation Swift dans Objective-C

11
Nicolai Dahl

Si Xcode génère réellement votre en-tête -Swift.h (au plus profond de DerivedData) mais ne fait pas référence à vos classes Swift, assurez-vous également qu'un en-tête de pontage est défini. La façon dont j'ai lu la documentation impliquait que je n'avais besoin de cela que pour appeler Objective-C depuis Swift, mais cela semble également nécessaire pour appeler Swift depuis Objective-C.

Voir ma réponse: https://stackoverflow.com/a/27972946/337392

EDIT: C’est à cause des modificateurs d’accès public et interne, comme je l’ai finalement trouvé, expliqué dans la documentation Apple: -

Par défaut, l'en-tête généré contient des interfaces pour les déclarations Swift marquées avec le modificateur public. Il contient également ceux marqués avec le modificateur internal si votre cible d'application a un en-tête de pontage Objective-C.

10
Echelon

Soutenir ce que beaucoup de gens ont ici, mais ajouter une capture d'écran pertinente. Swift et le code Obj-C peuvent certainement cohabiter. Ce n'est pas un jeu tout ou rien.

Pour accéder aux fichiers Swift de votre Objective-C, il vous suffit d'ajouter cet appel à votre fichier Obj-C (dans le fichier .m/implémentation):

#import "{product_module_name}-Swift.h"

(Où {product_module_name} représente le nom du module de produit de votre projet). Plutôt que d'essayer de deviner le nom du module de votre produit ou de déterminer les cas avec des espaces et des caractères spéciaux, allez simplement dans l'onglet Paramètres de construction du projet et tapez "nom du module de produit" - l'inspecteur vous révélera le vôtre. Le mien était quelque chose que je ne m'attendais pas à ce que ce soit. Regardez cette capture d'écran si vous êtes confus.

enter image description here

Et pour que le code Obj-c fonctionne dans Swift, il vous suffit d'ajouter un fichier d'en-tête de pontage et d'y importer les en-têtes Obj-C appropriés.

7
Brian Sachetta

Ok, voici tout ce dont vous avez vraiment besoin!

1. Supprimez tous les fichiers Swift que vous avez ajoutés et compilez le code, sans erreur éventuelle.

----------

enter image description here

----------

2.Accédez aux paramètres de construction "Projets" et définissez le nom du module du produit. Le projet doit avoir un nom de module de produit qui n'inclut pas d'espaces.

----------

enter image description here

----------

3.Defines Module doit être défini sur Yes dans les paramètres de construction, sous Packaging, dans votre projet, et non dans target!

----------

enter image description here

----------

4.Maintenant, créez un fichier Swift ou un contrôleur de vue, dans fichier-> newFile ->

----------

enter image description here

----------

Il vous demandera de créer un en-tête de pontage, lui permettant d'en créer un. Si vous l'avez refusé une fois, vous devrez ajouter manuellement un -Bridging-Header.h

5. Ajoutez @objc dans le contrôleur pour indiquer au compilateur qu'il existe un fichier Swift, qui doit être exposé à ObjectiveC

----------

enter image description here

----------

6.Construisez le projet et importez #import "-Swift.h" dans l'un des contrôleurs objectiveC, et tout fonctionnera! Vous pouvez tout en maintenant la touche Commande enfoncée pour voir le fichier réel!

----------

enter image description here

----------

J'espère que cela t'aides!

5
Kakshil Shah

Cette réponse concerne le cas d'utilisation dans lequel vous pourriez déjà avoir du code Objective-C qui appelle des classes Swift, puis vous commencez à recevoir cette erreur.

Comment résoudre le problème

Les étapes suivantes ont finalement résolu tous les problèmes pour moi. J'ai lu ci-dessus quelqu'un mentionnant le "poulet et l'œuf" et c'est précisément ce concept qui m'a conduit à cette procédure. Ce processus explicite montre qu'il faut supprimer toute classe de code Objective-C faisant référence à Swift jusqu'à la fin de la génération de l'en-tête.

  1. Mettez en commentaire l'instruction #import "ProductModuleName-Swift.h" dans votre fichier d'implémentation Objective-C.
  2. Mettez en commentaire toute référence dans le fichier d'implémentation d'Objective-C à Swift Classes
  3. Clean & Build
  4. Résoudre toutes les erreurs/avertissements
  5. Supprimer le commentaire sur l'instruction #import "ProductModuleName-Swift.h"
  6. Nettoyez et construisez (avec succès ou corrigez les erreurs restantes, , vérifiez que vous ne faites pas référence à aucune classe Swift dans Objective-C . Si c'est le cas temporairement, commentez-les)
  7. Vérifiez que "ProductModuleName-Swift.h" est généré par Cmd-Clicking sur le nom de classe de l'instruction #import "ProductModuleName-Swift.h".
  8. Supprimez le commentaire sur le code faisant référence aux classes Swift du fichier d'implémentation Objective-C.
  9. Nettoyer et construire normalement (le "ProductModuleName-Swift.h" doit être généré et votre code Objective-C faisant référence à Swift Les classes peuvent être utilisées normalement)

Nota Bene: Les réponses concernant la modification d'espaces en soulignés et le module Defines en YES comme indiqué ci-dessus s'appliquent toujours lors de l'exécution de ce processus, de même que les règles spécifiées dans le Documentation Apple .

Chemin de l'en-tête de pontage

Dans une erreur, le fichier ProductModuleName-Bridging-Header.h n'a pas été trouvé pendant le processus de génération. Ce fait a généré une erreur

<inconnu>: 0: erreur: en-tête de pontage '/Users/Shared/Working/abc/abc-Bridging-Header.h' n'existe pas

Une inspection plus minutieuse de l'erreur a indiqué que le fichier n'existerait jamais à l'emplacement décrit car il se trouvait réellement dans ( un chemin incorrect ).

'/Users/Shared/Working/abc/abc/abc-Bridging-Header.h'. une recherche rapide dans les paramètres de construction cible/projets pour effectuer la correction manuellement et le fichier abc-Swift.h a été à nouveau généré automatiquement.

build-settings

4
Tommie C.

La chose la plus importante est que Ce fichier est invisible !!! Au moins, il est dans Xcode6 beta5. Un tel fichier nommé "YourModule-Swift.h" ne figurera pas dans votre espace de travail. Assurez-vous simplement que vous avez le nom de module et que vous définissez le module défini sur yes, puis utilisez-le dans votre classe Objective-C.

4
user412759

Vous devez importer un en-tête dans les classes Objective-C, qui est:

#import “ProductModuleName-Swift.h”

Il est généré automatiquement. Sur la référence, il est indiqué "Tous les fichiers Swift de votre cible seront visibles dans les fichiers .bjective-C contenant cette instruction d'importation."

3
Anton

Juste un avertissement pour ceux qui ont utilisé "." dans le nom du projet. Xcode remplacera le "." avec un trait de soulignement "_" pour la version Swift du fichier d'en-tête de pontage. Curieusement, le Bridging-Header.h généré ne remplace pas les points par des traits de soulignement.

Par exemple, un projet portant le nom My.Project aurait les noms de fichier d’en-tête de pontage suivants.

Bridging-Header.h (Généré automatiquement)

My.Project-Bridging-Header.h

Swift.h

Mon_projet.h

J'espère que cela aidera tous ceux qui ont eu leurs règles et qui ont été bloqués comme moi. Ce fichier peut être trouvé à l'emplacement suivant.

Macintosh HD/Utilisateurs/ utilisateur /Bibliothèque/Développeur/Xcode/DerivedData/My.Project-fntdulwpbhbbzdbyrkhanemcrfil/Build/Intermediates/My.Project.build/Debug -iphonesimulator/My.Project.build/DerivedSources

Prends soin de toi,

Jon

2
jonthornham

Le projet doit avoir un nom de module sans espaces. Le module Defines doit être défini sur Oui dans les paramètres de construction, sous Conditionnement. a commenté la déclaration #import:

Si vous rencontrez toujours une erreur lors de l'importation de "ProductModuleName-Swift.h", alors

// # import "ProductModuleName-Swift.h"

qui a révélé un tas d'autres erreurs dans mon code Swift.

Une fois que j'ai corrigé ces nouvelles erreurs et obtenu la construction du code source avec succès, j'ai supprimé le commentaire #import et bingo! L'en-tête a été créé et importe correctement :)

2
j.krissa

n fichier réel dans le projet n'est pas créé ([ProductModuleName] -Swift.h). Cmd + Click sur l'import le génère à la volée (et en mémoire) pour vous permettre de voir comment le couplage est effectué, ou ouvre un fichier quelque part dans un répertoire de cache Xcode, mais ce n'est pas dans le répertoire de projet.

Vous devez définir Defines Module prop projet (dans les paramètres de construction de la cible) sur Yes et si le nom de votre module comporte des espaces ou des tirets, utilisez _ dans toutes les importations du [ProductModuleName]. Fichier -Sift.h.

Vous pouvez l'importer dans tous les fichiers .h et .m où vous utilisez les types Swift ou vous pouvez l'importer dans le fichier .pch.

Donc si mon module (projet) s'appelle "Test Project", je l'importerais comme ceci, dans le fichier .pch de mon projet (juste là):

#import "Test_Project-Swift.h"
2
Nikolay Tsenkov

J'ai trouvé un truc qui marche toujours sur moi.

  1. Créez votre #import "ProductModuleName-Swift.h" dans votre fichier appDelegate.h et dans votre fichier ProductName-Prefix.pch. Si vous ne l'avez pas dans xcode 6, vous pouvez le créer de cette façon Pourquoi ProjectName-Prefix.pch n'est-il pas créé automatiquement dans Xcode 6?
  2. Commande + Maj + K pour nettoyer votre code, si vous recevez une erreur concernant votre "ProductModuleName-Swift.h", supprimez-le du fichier appDelegate.h.
  3. Nettoyez votre code à nouveau. Maintenant tout va fonctionner comme un charme
  4. Si vous recevez à nouveau une erreur concernant le "ProductModuleName-Swift.h", créez à nouveau dans le fichier appDelegate.h et nettoyez à nouveau votre code.

Effectuez cette opération (supprimez et créez le fichier "ProductModuleName-Swift.h" à partir du fichier appDelegate.h et nettoyez votre code) chaque fois que vous recevez cette erreur pour la rendre silencieuse.

1
yannisalexiou

Dans mon cas, je devais définir la cible de déploiement sur au moins "OS X 10.9" et l'en-tête -Swift.h était automatiquement généré. N'oubliez pas que vous pouvez recevoir de nombreux avertissements de dépréciation lorsque vous modifiez la version cible du déploiement, notamment lorsque vous disposez d'une base de code Objective C plus ancienne et très volumineuse. Dans notre cas, nous avions également beaucoup de travail à faire dans les fichiers XIB et les classes de vues.

1
Rafael Bugajewski

J'avais du mal à déterminer le nom de mon module/l'import des en-têtes de Swift de objective-c. J'ai lu beaucoup d'articles ici aussi.

Mais la réponse définitive pour le nom de votre projet avec tous ses caractères spéciaux inclus (que ce soit "." Ou un chiffre ou un espace) - vous pouvez trouver le texte qui fonctionnera pour vous dans le champ " Nom du module de produit "sous les paramètres de construction de la cible.

Par exemple, mon nom de cible commençait par un chiffre - "1 mg" et le champ mentionné ci-dessus indiquait "_mg" comme nom de module.

j'ai donc utilisé #import "_mg-Swift.h" et cela a fonctionné.

Product Module Name in the build settings of target gives the correct module name which will work for your project

1
Keroberos

J'ai trouvé cette solution

  • Créer SwiftBridge.h
  • mettez #import “ProductModuleName-Swift.h”
  • Rendre ce fichier .h public (important) Sélectionnez le fichier -> Dans Afficher l'inspecteur de fichier (barre de droite) -> Rendez-le public

Maintenant vous pouvez

#import "SwiftBridge.h"

au lieu de ProductModuleName-Swift.h

Ceci est une solution de contournement. Pour la prochaine version de Xcode, je pense que ce problème sera résolu. Bonne chance

1
Tot FOURLEAF

Si vous utilisez quelque chose comme Cocoapods (et travaillez hors de l'espace de travail plutôt que du projet), essayez d'ouvrir le projet et de le construire avant d'ouvrir l'espace de travail et le bâtiment. YMMV.

0
Warpling

J'ai dû supprimer le code WatchOS2 Swift de mon projet Objective C. Et seulement après que XCode a proposé de générer -Swift.h

0
Andrew Marin

Le fichier était en cours de génération mais Xcode ne pouvait pas le trouver (j'ai utilisé la réponse de Lou Zell pour prouver qu'il était généré).

C'était mon correctif (Xcode 9.2) pour un framework mixte ObjC/Swift:

  1. Recherchez le fichier généré attendu dans DerivedData en effectuant une recherche dans le Finder (TargetName-Swift.h).
  2. Faites-le glisser dans votre projet en XCode et DÉCOCHEZ copier les fichiers.
  3. Cliquez sur le fichier dans XCode et ouvrez le Inspecteur de fichier (premier onglet du panneau de droite).
  4. Remplacez Emplacement de Par rapport au groupe par Par rapport aux produits de construction

Les deux premières étapes devraient vous permettre de construire et d’utiliser votre projet parfaitement, mais les deux dernières lui permettent de fonctionner sur d’autres ordinateurs (c’est-à-dire qu’il fonctionne toujours lors de la collaboration sur un projet d’équipe).

0
rmooney

Cela peut être un point évident (peut-être trop évident), mais vous devez avoir au moins un fichier Swift dans le projet pour que l'en-tête soit généré. Si vous écrivez du code standard ou du code de configuration avec l'intention d'écrire plus tard Swift, l'importation ne fonctionnera pas.

0
Alex Brown

J'avais un problème similaire mais mon projet compilait avant et a soudainement eu une erreur après quelques changements de code de fichiers. Il m'a fallu du temps pour comprendre pourquoi je reçois l'erreur 'Fichier non trouvé' pour le fichier myproject-Swift.h. Les modifications de code que j'avais effectuées comportaient des erreurs. Xcode n'a pas mis ces erreurs à la place de tous les temps en affichant le message "Fichier non trouvé d'erreur". Ensuite, j'ai obtenu une copie du code de la version précédente et j'ai comparé le nouveau code et le fichier fusionné un par un. Après chaque fusion de fichiers, le projet s'est conformé pour rechercher l'erreur. Donc, si vous avez une erreur dans votre code, Xcode peut simplement afficher "erreur de fichier non trouvé" pour le fichier myproject-Swift.h. Très probablement, vous avez une erreur de compilation dans votre projet. Nettoyez ces erreurs et cela fonctionnera.

0
Ram G.

Parfois, il vous suffit de désélectionner, puis de redéfinir l’appartenance cible sur le fichier obj-c .m.

0
valeCocoa

Si vous pouviez créer un projet auparavant, sans aucun problème lié à l'erreur “ProductModuleName-Swift.h” not found, et que maintenant vous obtenez à nouveau ces vilaines erreurs, il se peut que la raison soit conservée dans vos modifications récentes.

Pour moi, c'était par (accidentel) incorrect _ codage de fichier .Swift. Annuler les modifications et ramener les données manuellement fait le travail.

0
Yevhen Dubinin