Swift to Objective-C header non créé dans Xcode 6

J’ai récemment travaillé pour append 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 pour obtenir le “Bridging Header”, c’est-à-dire Objective-C, pour Swift.

Mais le fichier d’en-tête -Swift.h qui est censé exposer les classes Swift marquées soit @objc, soit des sous-classes de classes ObjC, est introuvable 🙁

Je ne vois pas d’instructions spécifiques sur la façon de réaliser l’utilisation de ma nouvelle sous-classe, écrite en Swift, dans mon code d’application principal (qui est toujours Obj-C).

L’application dont je suis le développeur principal possède une base de code assez large (70 000 lignes), il est donc impossible de la transférer en une fois.

Maintenant ça marche.

  1. Le projet doit avoir un nom de module de produit qui ne comprend pas d’espaces.
  2. Defines Module doit être défini sur Yes dans Build Settings, sous Packaging.

Fonctionne enfin. Merci à tous pour votre aide 🙂

J’ai eu un problème similaire et trouvé que vous ne pouvez append que

#import “ProductModuleName-Swift.h”

fichiers obj-c .m, pas les fichiers .h pour trouver l’en-tête parapluie

J’ai constaté que je devais corriger toutes les erreurs de génération avant de générer le fichier.

Le problème pour moi était que c’était un problème de poulet / œuf, en ce sens que je ne voyais aucune erreur de construction tant que je n’avais pas commenté la commande #import :

//#import "ProductModuleName-Swift.h"

ce 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 le code source avec succès, j’ai décommenté le #import et le bingo! L’en-tête a été créé et importé correctement 🙂

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

Par exemple, si le nom de votre projet est “Mon projet”, vous utiliseriez:

# Import “My_Project-Swift.h”

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

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

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

J’utilise la version 6.2 de Xcode (6C86e)

* La seule chose importante est: *

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

 #import -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 “Définit le module” est défini sur Oui ou Non ou si le projet “Nom du module de produit” n’est pas défini.

Rappel: les classes Swift doivent dériver de NSObject ou être associées à l’atsortingbut @objc pour être exposées à ObjectiveC / Foundation || cocoa …

Je voulais append une autre raison pour laquelle vous pourriez trouver un problème avec ceci: je créais un cadre qui mélangeait le code Swift et Objective-C. Je n’ai pas pu importer les classes Swift en dehors du framework – j’ai vérifié le fichier -Swift.h et il était généré mais était vide.

Le problème s’est avéré très simple: je n’avais déclaré aucune de mes classes Swift en public! 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 framework.

A noter également que dans le framework (à l’intérieur des fichiers .m uniquement comme mentionne une autre réponse), je devais importer le fichier -Swift.h en tant que:

 #import  

J’ai eu le même problème. Il semblerait que vous deviez ajuster les parameters (Définit le nom du module et du module de produit) avant d’append 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 créez-en un nouveau.

Voici une autre variante du moduleName-Swift.h non généré.

J’ai décidé d’inclure les graphiques IOS dans mon projet, mais je ne voulais pas mélanger les sources dans le même répertoire. J’ai donc placé le dossier Projet Charts à côté du dossier de projet de mon code. J’ai glissé le projet Graphiques dans la barre de navigation de mon projet et inclus le cadre dans la liste Fichiers binarys incorporés de la cible de projet dans les parameters généraux du projet et défini le commutateur Emballage de contenu incorporé sur Oui dans l’onglet Paramètres de construction de mon projet.

Le fichier moduleName-Swift.h de mon projet ne génèrerait jamais quels que soient les autres commutateurs ou parameters proposés ici. Enfin, en utilisant la méthode de Lou Z pour rechercher les fichiers -Swift.h, j’ai vu qu’un fichier Charts-Swift.h était généré en profondeur dans le répertoire xcode Build de mon projet dans Charts.framework / Headers /

La solution pour utiliser le package Swift de ios-charts de Daniel Gindi sans inclure le code dans le répertoire source de mon projet était d’append:

 #import "Charts/Charts-Swift.h" 

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

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

Une façon de gérer cela est

  1. Ajoutez un préprocesseur pour chacune de vos cibles qui est le nom de votre cible elle-même (sans espaces). Ex. MY_TARGET=1 . Ajoutez ceci dans Paramètres du projet-> Paramètres de construction-> 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 un fichier PCH, ajoutez simplement ces mêmes lignes dans un seul en-tête et incluez cet en-tête où vous devez utiliser les classes swift.

Cela devrait bien fonctionner.

Permettez-moi de partager mes expériences en essayant d’utiliser Swift dans un ancien projet objc. Je n’ai pas eu à définir le Defines module sur YES .

Dans mon cas, je devais m’assurer manuellement qu’il y avait un en-tête de pontage objc. Seul le nom d’en-tête d’interface généré était présent dans mes parameters de génération.

En-tête de pontage manquant

Cela a conduit à un fichier MyApp-Swift.h à générer, mais sans aucune trace de mes classes Swift.

La documentation Apple indique que vous serez invité à créer un en-tête de pont lors de l’ajout de votre premier fichier rapide. Eh bien, je ne l’étais pas. J’ai ajouté manuellement un MyApp-Bridging-header.h et l’ MyApp-Bridging-header.h pointé dans le champ “Objective-C Bridging Header”. Cela a rendu mon fichier MyApp-Swift.h rempli avec mes classes Swift.

Docs: Importation de Swift dans Objective-C

Si XCode génère réellement votre en-tête -Swift.h (profondément dans DerivedData) mais qu’il ne fait pas référence à vos classes Swift, assurez-vous que vous avez également un en-tête de pont défini. La façon dont je lisais les documents impliquait que je n’avais besoin que de cela pour appeler Objective-C depuis Swift, mais cela semblait 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’access publics et internes, 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 du modificateur interne si votre cible d’application possède un en-tête de pontage Objective-C.

Appuyant ce que beaucoup de gens ont ici, mais en ajoutant 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 dans votre Objective-C, il vous suffit d’append cet appel à votre fichier Obj-C (dans le fichier .m / implementation):

 #import "{product_module_name}-Swift.h" 

(Où {nom_module_produit} 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 trouver des cases d’angle avec des espaces et des caractères spéciaux, accédez à l’onglet Paramètres du projet et tapez “nom du module du produit”. L’inspecteur vous le révélera. Le mien était quelque chose que je ne m’attendais pas à être. Découvrez cette capture d’écran si vous êtes confus.

entrer la description de l'image ici

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

Ok, voici toutes les choses dont vous avez vraiment besoin!

1.Retirez tous les fichiers swift que vous avez ajoutés et comstackz le code sans erreur.

———-

entrer la description de l'image ici

———-

2. Accédez aux parameters de construction “Projets” et définissez le nom du module du produit. Le projet doit avoir un nom de module de produit qui ne comprend pas d’espaces.

———-

entrer la description de l'image ici

———-

3.Defines Module doit être défini sur Yes dans Build Settings, sous Packaging, dans votre projet et non comme cible!

———-

entrer la description de l'image ici

———-

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

———-

entrer la description de l'image ici

———-

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

5.Ajouter @objc dans le contrôleur pour indiquer au compilateur qu’il existe un fichier rapide qui doit être exposé à ObjectiveC

———-

entrer la description de l'image ici

———-

6.Construisez le projet et importez #import “-Swift.h” dans l’un des contrôleurs objectiveC, et cela fonctionnera! Vous pouvez cliquer dessus pour voir le fichier!

———-

entrer la description de l'image ici

———-

J’espère que cela t’aides!

La chose la plus importante est que ce fichier est invisible !!! Au moins, c’est dans Xcode6 beta5. Il n’y aura pas de fichier nommé “YourModule-Swift.h” dans votre espace de travail. Assurez-vous que vous avez le nom du module et définissez le module défini sur yes, et utilisez-le dans votre classe Objective-C.

Cette réponse concerne le cas d’utilisation où vous avez peut-être déjà du code Objective-C qui appelle les 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 la “poule et l’oeuf” et c’est exactement ce concept qui m’a amené à cette procédure. Ce processus explicite montre qu’il faut supprimer tout code Objective-C référençant les classes Swift jusqu’à ce que l’en-tête soit généré.

  1. Commentez l’instruction #import “ProductModuleName-Swift.h” dans votre fichier d’implémentation Objective-C
  2. Commentez les références dans le fichier d’implémentation Objective-C aux classes Swift
  3. Clean & Build
  4. Résoudre toutes les erreurs / avertissements
  5. Supprimez le commentaire sur l’instruction #import “ProductModuleName-Swift.h”
  6. Clean & build (réussissez ou corrigez toutes les erreurs restantes, vérifiez que vous ne faites référence à aucune classe Swift dans Objective-C à ce stade . Si c’est le cas, mettez-les en commentaire temporairement)
  7. Vérifiez que “ProductModuleName-Swift.h” est généré par Cmd-cliquant sur le nom de classe de l’instruction #import “ProductModuleName-Swift.h”
  8. Supprimez le commentaire sur le code référençant les classes Swift dans le fichier d’implémentation Objective-C.
  9. Clean & Build normal (le “ProductModuleName-Swift.h” doit être généré et votre code Objective-C référençant les classes Swift peut être utilisé normalement)

Nota Bene: Les réponses concernant le changement d’espaces en caractères de soulignement et le module Defines to YES, tel qu’il est indiqué ci-dessus, s’appliquent toujours lors de l’exécution de ce processus, tout comme les règles spécifiées dans la documentation Apple .

Traverser le chemin de l’en-tête

En une erreur, le fichier ProductModuleName-Bridging-Header.h n’était pas trouvé lors du processus de génération. Ce fait a généré une erreur

: 0: erreur: l’en-tête de pontage ‘/Users/Shared/Working/abc/abc-Bridging-Header.h’ n’existe pas

Un examen plus attentif de l’erreur a indiqué que le fichier n’existerait jamais à l’emplacement décrit, car il se trouvait réellement à ( un mauvais chemin )

‘/Users/Shared/Working/abc/abc/abc-Bridging-Header.h’. une recherche rapide des parameters de construction cible / projets pour effectuer la correction manuellement et le fichier abc-Swift.h a été à nouveau généré automatiquement.

paramètres de construction

Vous devez importer un en-tête dans les classes Objective-C, c’est-à-dire:

 #import “ProductModuleName-Swift.h” 

Il est généré automatiquement, sur la référence, il est dit “Tous les fichiers Swift de votre cible seront visibles dans les fichiers Objective-C .m contenant cette instruction d’importation.”

Un fichier réel dans le projet n’est pas créé ([ProductModuleName] -Swift.h). Cmd + Clic sur l’importation le génère à la volée (et en mémoire) afin que vous puissiez voir comment la liaison est faite, ou ouvre un fichier quelque part dans un répertoire de cache Xcode, mais ce n’est pas dans le répertoire du projet.

Vous devez définir le prop de projet Defines Module (dans les parameters de build de la cible) sur Yes et si le nom de votre module comporte des espaces ou des tirets – utilisez _ dans toutes les importations du fichier [ProductModuleName] -Swift.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 ça, dans le fichier .pch de mon projet (juste là):

 #import "Test_Project-Swift.h" 

Juste un avertissement pour quiconque a 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 qui est généré ne remplace pas les périodes avec des soulignés.

Par exemple, un projet avec le nom My.Project aura les noms de fichier en-tête de pont suivants.

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

My.Project-Bridging-Header.h

Swift.h

My_Project.h

J’espère que cela aidera quiconque a utilisé une période et a été coincé comme je l’étais. Ce fichier peut être trouvé à l’emplacement suivant.

Macintosh HD / Utilisateurs / utilisateur /Library/Developer/Xcode/DerivedData/My.Project-fntdulwpbhbbzdbyrkhanemcrfil/Build/Intermediates/My.Project.build/Debug-iphonesimulator/My.Project.build/DerivedSources

Prends soin,

Jon

Le projet doit avoir un nom de module sans espaces. Defines Module doit être défini sur Yes dans Build Settings, sous Packaging. 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”

ce 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 le code source avec succès, j’ai décommenté le fichier #import et le bingo! L’en-tête a été créé et importé correctement 🙂

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 + shift + 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 fonctionnera comme un charme
  4. Si vous recevez à nouveau une erreur concernant le “ProductModuleName-Swift.h”, créez à nouveau le fichier appDelegate.h et nettoyez à nouveau votre code.

Faites ce travail (supprimez et créez le “ProductModuleName-Swift.h” du fichier appDelegate.h et nettoyez votre code) chaque fois que vous recevez cette erreur pour la désactiver.

J’ai trouvé cette solution

  • Créer SwiftBridge.h
  • mettre #import “ProductModuleName-Swift.h”
  • Rendre ce fichier .h public (important) Sélectionnez le fichier -> Dans Afficher le fichier Inspecteur (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

J’avais du mal à déterminer mon nom de module / importation d’object-c des en-têtes de swift. J’ai lu beaucoup d’articles ici aussi.

Mais la réponse définitive au nom de votre projet avec tous ses caractères spéciaux inclus (que ce soit “.” Ou un nombre ou un espace) – vous pouvez trouver le texte qui fonctionnera pour vous dans le ” Nom du module de produit ” dans les parameters de construction de la cible. .

Par exemple, mon nom cible a commencé par un chiffre – “1mg” et le champ mentionné ci-dessus a indiqué “_mg” comme nom de module.

J’ai donc utilisé #import “_mg-Swift.h” et cela a fonctionné.

Nom du module de produit dans les paramètres de construction de la cible donne le nom du module correct qui fonctionnera pour votre projet

Dans mon cas, j’ai dû définir la cible de déploiement sur au moins «OS X 10.9» et l’en -Swift.h tête -Swift.h été automatiquement généré. Gardez à l’esprit que vous pouvez obtenir beaucoup d’avertissements lors de la modification de la version cible du déploiement, en particulier lorsque vous disposez d’une base de code Objective C plus ancienne et de grande taille. Dans notre cas, nous avons également beaucoup de travail à faire dans les fichiers XIB et les classes de vue.

Si vous étiez en mesure de créer un projet auparavant, sans problème lié à “ProductModuleName-Swift.h” not found cette erreur, la raison pourrait en être à vos récentes modifications.

Pour moi, c’était par un codage (accidentel) incorrect .swift fichier .swift . Inverser les modifications et ramener manuellement le dossier, fait le travail.

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

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

J’ai eu un problème similaire mais mon projet était en train de comstackr avant et a soudain eu une erreur après quelques changements de code de fichiers. Il m’a fallu du temps pour comprendre pourquoi j’obtiens l’erreur “Fichier non trouvé” pour le fichier myproject-swift.h. Les modifications de code que j’avais effectuées avaient des erreurs. Xcode n’a pas indiqué mettre ces erreurs à la place tout en affichant “l’erreur de fichier non trouvé”. Ensuite, j’ai obtenu une copie du code de la version précédente et j’ai comparé avec le nouveau code et le fichier fusionné un par un. Après chaque fusion de fichiers conforme au projet pour trouver l’erreur. Donc, si vous avez une erreur dans votre code, Xcode peut simplement afficher «fichier erreur non trouvée» pour le fichier myproject-swift.h. Vous avez probablement des erreurs de compilation dans votre projet. Nettoyez ces erreurs et cela fonctionnera.

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

Parfois, il vous suffit de désactiver, puis de définir à nouveau l’adhésion cible sur le fichier obj-c .m.