objective-c - how - objective c to swift




L'en-tête Swift to Objective-C n'est pas créé dans Xcode 6 (20)

J'ai récemment travaillé pour ajouter Swift à un projet existant, pour arriver à l'essayer dans un mode réel.

Lors de l'ajout d'un fichier source Swift au projet, je n'ai aucun problème à obtenir le "Bridging Header", c'est-à-dire Objective-C à Swift.

Mais le fichier d'en-tête -Swift.h censé exposer les classes Swift marquées @objc ou sous-classes de classes ObjC, est introuvable :-(

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

L'application dont je suis le développeur principal a une base de code assez large (70.000 lignes), donc la transition en une seule fois est hors de question.


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 soit généré. Si vous écrivez un texte standard ou un code de configuration avec l'intention d'écrire rapidement, l'importation ne fonctionnera pas.


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

Comment réparer 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'oeuf" et c'est exactement ce concept qui m'a conduit à 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 vers les classes Swift
  3. Nettoyer et construire
  4. Résoudre toutes les erreurs / avertissements
  5. Supprimez le commentaire sur l'instruction #import "ProductModuleName-Swift.h"
  6. Nettoyer et construire (avec succès ou corriger les erreurs restantes, vérifiez que vous ne faites référence à aucune classe Swift dans Objective-C à ce stade .
  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. Supprime le commentaire sur le code référençant les classes Swift dans le fichier d'implémentation Objective-C.
  9. Clean & Build comme d'habitude (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 à propos de la modification des espaces pour les underscores et du module Defines à YES comme 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 .

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 construction. Ce fait a généré une erreur

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

Une inspection plus approfondie de l'erreur a indiqué que le fichier n'existerait jamais à l'emplacement décrit parce qu'il se trouvait réellement à ( un mauvais chemin )

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


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


J'ai eu le même problème. Il semble que vous deviez ajuster les paramètres (Définit le nom du module et du module de produit) avant d'ajouter votre premier fichier Swift.

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


J'ai eu un problème similaire mais mon projet était en train de compiler 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 une erreur 'Fichier non trouvé' pour le fichier myproject-swift.h. Les changements de code que j'avais fait avaient quelques erreurs. Xcode ne pointait pas mettre ces erreurs à la place tout le temps montrant l'erreur 'Fichier non trouvé'. Puis j'ai obtenu la 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 fichier a respecté le projet pour trouver l'erreur. Donc la ligne du bas est que si vous avez une erreur dans votre code, Xcode peut simplement afficher 'erreur 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.


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 l'inspecteur de fichier (barre de droite) -> Rendre public

Maintenant vous pouvez

#import "SwiftBridge.h"

au lieu de ProductModuleName-Swift.h

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


J'ai trouvé un truc qui fonctionne 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 manière. 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 à propos de 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 à propos de "ProductModuleName-Swift.h", créez à nouveau dans le fichier appDelegate.h et nettoyez à nouveau votre code.

Faites ce travail (supprimer et créer le "ProductModuleName-Swift.h" du fichier appDelegate.h et nettoyer votre code) chaque fois que vous recevez cette erreur pour le faire taire.


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

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

Par exemple mon nom de cible a commencé avec un "- 1mg" numérique et le champ mentionné ci-dessus a montré "_mg" comme mon nom de module.

J'ai donc utilisé # import "_mg-Swift.h" et ça a marché.


Juste un heads-up pour quiconque a utilisé "." là nom du projet. Xcode remplacera le "." avec un trait de soulignement "_" pour la version Swift du fichier d'en-tête de pontage. Assez curieusement, le Bridging-Header.h qui est généré ne remplace pas les périodes avec des underscores.

Par exemple, un projet portant le nom My.Project aura les noms de fichier Bridging Header suivants.

Bridging-Header.h (autogénéré)

My.Project-Bridging-Header.h

Swift.h

My_Project.h

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

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

Prends soin,

Jon


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 simplement d'avoir le nom du module et définissez le module sur yes, et utilisez-le dans votre classe Objective-C.


Le projet doit avoir un nom de module n'incluant pas d'espaces. Définit le module doit être défini sur Oui dans les paramètres de construction, sous Emballage. a commenté l'instruction # import:

Si vous avez encore 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 le bâtiment source avec succès, j'ai décommenté le #import et le bingo! L'en-tête a été créé et importé correctement :)


Maintenant ça marche.

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

Enfin fonctionne. Merci à tous pour votre aide :-)


Parfois, vous avez juste besoin de désactiver, puis redéfinir l'appartenance à la cible dans le fichier obj-c .m.


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

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

Cela conduit à un fichier MyApp-Swift.h à être généré, 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 MyApp-Bridging-header.h et je l'ai pointé dans le champ "Objective-C Bridging Header". Cela a fait que mon fichier MyApp-Swift.h soit rempli avec mes classes Swift.

Docs: Importation de Swift en Objective-C


Si XCode génère réellement votre en-tête -Swift.h (au cœur de DerivedData) mais ne se réfère pas à vos classes Swift, assurez-vous que vous avez également un en-tête de pontage défini. La façon dont je lisais les docs impliquait que j'avais seulement besoin de ça pour appeler Objective-C de Swift, mais il semble nécessaire d'appeler Swift de l'Objective-C aussi.

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

EDIT: C'est à cause des modificateurs d'accès public vs interne, comme je l'ai finalement trouvé expliqué dans les docs d'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 interne si votre cible d'application a un en-tête de pontage Objective-C.


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 utiliserez:

#import "My_Project-Swift.h"


Si vous êtes comme moi, vous avez probablement mal le nom de l'en-tête. Après avoir mal à la tête pendant un moment, j'ai cherché le fichier dans DerivedData et je suis sûr qu'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)


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.


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

#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 déclaration d'importation."


* La seule chose importante est: *

pour utiliser le "Product Module Name" 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 "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 avoir été taguées avec l'attribut @objc afin d'être exposées à ObjectiveC / Foundation || Cacao ...







swift