web-dev-qa-db-fra.com

NomModule-Swift.h fichier non trouvé dans xcode8

J'essaie de travailler sur un projet mixte Swift et ObjectiveC sans succès.

Mon projet est composé de 6 cibles:

  • App
  • Coeur
  • CoreTest
  • Résumé
  • WatchKit Extension
  • WatchKit App

J'ai pu ajouter une classe Swift ayant une appartenance cible (App) et utilisant le code ObjectiveC transmis depuis le App-Bridging-Header.h Le paradigme "ObjectiveC into Swift code" fonctionne comme un charme.

Au lieu de cela, je lutte avec le paradigme "Swift into ObjectiveC code" . Dans le cas spécifique, je dois utiliser une nouvelle classe Swift dans un fichier ObjectiveC .m membre de quatre cibles.

Ce que j'ai fait jusqu'à présent est la suivante:

  1. Ajouter un nouveau fichier Swift au projet Core en spécifiant les quatre appartenances (App, Core, Résumé, WatchKit Ext)
  2. XCode demande à créer -Bridging-Header.h pour trois projets Core, Summary et WatchKit Ext (App-Bridging-Header.h existe déjà car il a déjà été utilisé), et j'accepte (je ne sais pas pourquoi crée ces fichiers dans le même dossier de groupe où j'ajoute ma classe Swift mais tant pis)
  3. Je crée la classe Swift en ajoutant la clé @objc avant class
  4. Je vais vérifier si le nom d'en-tête d'interface générée Objective-C est défini pour tous les modules, et c'est le cas
  5. Je vais vérifier si Defines Module est défini sur No dans tous les modules et sur Yes dans le projet principal, et oui, il l'est
  6. J'écris les importations pour les fichiers -Swift.h pour les quatre cibles
  7. Dans ma classe Objective-C, j'essaie d'utiliser ma nouvelle classe Swift. Apparemment, cela semble fonctionner (même l'auto-complétion).
  8. J'essaie de construire le projet mais je ne parviens pas à dire que le fichier -Swift.h est introuvable.

J'ai suivi le guide Mix and Match de Apple et beaucoup SO - fils de discussion comprenant celui-ci qui semble apparemment résoudre le même problème mais il ne fonctionne pas.

J'ai également vu ceci et ceci mais n'a pas fonctionné.

J'ai également essayé de supprimer les données dérivées et de nettoyer le projet dans son intégralité plusieurs fois sans succès.

EDIT 1: Plus de détails

Ceci est la déclaration de ma classe Swift importer RealmSwift

@objc class MyClass: Object {}

C’est le bout d’utilisation de la classe Swift dans ObjectiveC

MyClass *app = [[MyClass alloc] init];

Si j'évite d'utiliser #import ...- Swift.h, la construction échoue en indiquant que je me sers d'un identificateur non déclaré "MyClass" et que le son est bon.

Si j’utilise les fichiers #import ...- Swift.h, cela signifie que le module X ne peut pas trouver le module Y, etc.

EDIT 2: nom du module Swift

En examinant la propriété Swift_OBJC_INTERFACE_HEADER_NAME de chaque cible, j'ai constaté qu'elle est construite à l'aide de cette syntaxe $ (Swift_MODULE_NAME) -Swift.h dois-je modifier Swift_MODULE_NAME en MODULE_NAME?

EDIT 3: Importations

Voici l'ensemble des importations pour les en-têtes Swift dans le fichier .m ObjectiveC . J'utilise les noms de module spécifiés dans les propriétés relatives aux paramètres de construction. Notez que l’un a le caractère '_' car la cible de WatchKit Extension a un espace dans le nom de la cible.

#import "ProjectName_App-Swift.h"
#import "ProjectName_Core-Swift.h"
#import "ProjectName_Summary-Swift.h"
#import "ProjectName_WatchKit_Extension-Swift.h"

EDIT 4: Visibilité croisée des fichiers -Swift.h

J'ai essayé ce qui suit:

  • Ajout d'une classe Swift uniquement dans l'application cible
  • XCode a créé l'en-tête de pontage
  • #Import "ProjectName_App-Swift.h" inséré dans le fichier ObjectiveC utilisé uniquement par App
  • Utilisation de la classe Swift dans ce fichier
  • Il compile! Et je suis capable d'utiliser la classe Swift

Lorsque la classe Swift est définie pour plusieurs cibles et que le fichier ObjectiveC est utilisé par ces cibles multiples, cela ne fonctionne pas. Les erreurs de construction sont les suivantes: Target X -> Fichier "ProjectName_TargetY-Swift.h" introuvable . Apparemment, une cible ne peut pas voir les autres fichiers de cibles -Swift.h.

Qu'est-ce que je fais mal? Merci pour votre aide

25
LucioB

L’hypothèse que j’ai faite dans Edit 4 s’est avérée être la bonne . Si un projet a plusieurs cibles, les fichiers "-Swift.h" ne peuvent pas être importés dans un fichier .m ObjectiveC.

Il faut donc adopter une solution: modifier le paramètre de construction Swift_OBJC_INTERFACE_HEADER_NAME et le rendre identique pour différentes cibles . Pour ce faire, modifiez l'instruction qui génère cette propriété à partir de $ (Swift_MODULE_NAME ) -Swift.h à $ (PROJECT_NAME) -Swift.h comme expliqué ici

Il est également possible de définir le paramètre Nom du module de produit dans les paramètres de construction de manière à ce qu'il soit identique dans tous vos modules (je l'ai défini sur $ (PROJECT_NAME)), de sorte que le fichier -Swift.h généré soit identique dans tous les modules. . Cela élimine la nécessité d'ajouter/de vérifier les macros du préprocesseur.

Après avoir nettoyé le dossier de construction, appuyez sur Alt et accédez au menu Produit. Comme le nom de l'en-tête est partagé entre les cibles, il peut maintenant être importé une fois dans le fichier .m ObjectiveC et toutes les cibles peuvent bénéficier des classes Swift.

Si, après la construction, l'erreur persiste, assurez-vous que l'en-tête est accessible à partir de XCode en cliquant sur son nom. Il devrait ouvrir un fichier contenant du code similaire à ceci:

Swift_CLASS("_TtC27ProjectName_Summary11MyClass")
@interface MyClass : NSObject
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end

Si vous devez vous assurer que ces en-têtes sont générés, ouvrez un terminal et utilisez cette commande 

find ~/Library/Developer/Xcode/DerivedData -name "*Swift.h"

Vous devriez voir un en-tête pour chaque cible

Un autre problème qui m’est arrivé après ces changements est qu’il a commencé à donner des erreurs sur le code ObjectiveC que je n’ai pas touchées. Le problème était dû à la position de l'importation, comme indiqué ici :

En haut du fichier .m, vous importez l'en-tête de pontage masqué qui peut faire la différence. Le signe habituel de problème est que vous obtenez une erreur de compilation «Nom de type inconnu», où le type inconnu est une classe déclarée dans Objective-C. La solution consiste à # importer le fichier .h contenant également la déclaration du type inconnu dans vos fichiers Objective-C, avant d'importer l'en-tête de pontage masqué. Cela peut être une gêne, en particulier si le fichier Objective-C en question n'a pas besoin de connaître cette classe, mais qu'il résout le problème et permet à la compilation de continuer.

A la toute fin, le code est compilé et exécuté sur un appareil et un simulateur!

38
LucioB

La solution pour moi consistait à importer l'en-tête Swift généré via la syntaxe <>:

#import <OtherTargetWithSwiftClass/OtherTargetWithSwiftClass-Swift.h>
6
cornr

Ce n'est pas une solution à la question mais beaucoup d'entre eux pourraient se retrouver sur cette page à la recherche du problème que le fichier <ModuleName>-Swift.h est introuvable (tout comme moi). J'aimerais ajouter une raison supplémentaire: 

Lorsqu'il y a un problème de compilation dans un fichier Swift, l'en-tête peut ne pas être généré par Xcode et le fichier est donc manquant. 

Au moins dans mon cas, le <ModuleName>-Swift.h not found avait disparu une fois que j'avais corrigé l'erreur de compilation dans le fichier Swift. 

5
Jens

J'avais un problème similaire et j'ai presque fini par passer toute une journée à résoudre le problème tout en suivant les suggestions d'autres développeurs sur StackOverflow et quelques autres sources.

J'étais en train de passer de Xcode 7.3.1 à Xcode 8.2.1 et de Swift 2.2 à Swift 3.0.1.
Dans mon cas, j'ai découvert que le fichier PROJECT_NAME-Swift.h n'a pas été créé à: 

~/Library/Developer/Xcode/DerivedData/PRODUCT-NAME-hdkrxixrxbiorwesffpqvefxsrzl/Build/Intermediates/PRODUCT-NAME.build/Debug/PRODUCT-NAME.build/Objects-normal/x86_64/PRODUCT-NAME-Swift.h. 

J'imagine qu'il essaie en quelque sorte de faire référence à ce fichier d'en-tête à partir du chemin ci-dessus et donc de l'erreur. Je l'ai copié manuellement. N'a pas fait de nouvelle génération après cela . Cela a résolu mon problème et le fichier d'en-tête Swift a commencé à être créé pour une compilation et des générations supplémentaires.

2
retrocoder84

Dans mon cas, j'ai un espace de travail avec un sous-projet d'application iOS, un sous-projet d'infrastructure et un sous-projet CocoaPods Pods. L'erreur "Fichier ModuleName-Swift.h introuvable" s'est produite dans mon sous-projet de cadre car le fichier n'avait pas encore été créé par le sous-projet Pods.

Je ne sais pas s'il existe un moyen de renseigner Xcode sur les dépendances entre sous-projets, mais je les ai simplement réordonnés dans le navigateur de projet de gauche:

  1. Pods
  2. cadre
  3. app iOS

A bien fonctionné après ça!

0
ScottyB

Pour mon cas, cela fonctionne bien dans Xcode 8 mais les fichiers avec 

#import "Project-Swift.h"

a des importations manquantes comme décrit par LucioB

Utiliser Xcode 9 supprime ces erreurs

0
Ted