Xcode 6 / Beta 4: l'utilisation d'en-têtes de pontage avec des cibles de structure n'est pas prise en charge


131

Je viens de passer à Xcode 6 Beta 4 et j'ai un framework que j'ai créé pour Live Views dans Beta 2. En raison d'un autre bug rapide , j'ai dû utiliser du code Obj-C. Lors de la mise à niveau, j'obtiens l'erreur suivante:

erreur: l'utilisation d'en-têtes de pontage avec des cibles de structure n'est pas prise en charge

Je n'ai rien vu dans les notes de publication, ni trouvé aucun autre chemin de migration. Quelqu'un d'autre a-t-il vu cela et est-il arrivé à une solution?

Je me rends compte que la bêta 3 a éliminé le besoin de cadres pour les vues en direct, mais cela a du sens dans mon cas si je peux le faire fonctionner. Je peux cependant le supprimer comme solution de secours, mais je préférerais utiliser un framework s'ils ne sont pas totalement cassés dans la bêta 4.


"Je me rends compte que la Beta 3 a éliminé le besoin de cadres". Comment?
hnh le

2
(pour les vues en direct) - modifié
Chris Conover

1
Je rencontre le même problème.
Simon Germain

2
Wow, votre petite modification là-bas a rendu ma vie tellement meilleure - je n'ai entendu parler de ce changement (éliminant le besoin de frameworks) nulle part et me cognait la tête avec toutes ces cibles de framework pour des vues en direct pendant des heures. Merci beaucoup pour ce @chrisco!
yonix

Réponses:


232

Comme l'indique l'erreur, les en-têtes de pontage ne sont pas autorisés dans Frameworks. La section Importing Code from Within the Same Framework Target de la documentation Apple Mix & Match y fait allusion. Comme on dit, vous devez "Dans votre fichier d'en-tête parapluie, importez chaque en-tête Objective-C que vous souhaitez exposer à Swift".

Cependant, j'ai découvert que vous devrez peut-être également rendre ces en-têtes spécifiques publics. Cette réponse examine pourquoi et comment faire cela: Erreur du compilateur Swift: "en-tête non modulaire à l'intérieur du module de structure" .

Alors, faites ceci:

  1. Supprimez votre fichier d'en-tête de pontage.
  2. Supprimer les références au fichier d'en-tête de pontage dans les paramètres de construction du framework
  3. Ajoutez les en-têtes nécessaires à votre fichier parapluie ([ProductName] .h)
  4. Rendez les fichiers inclus publics dans la section "En-têtes" du framework de ses "Phases de construction".
  5. Nettoyez et reconstruisez.

Remarque : Le «fichier d'en-tête parapluie» est un fichier (nommé [ProductName] .h) qui représente généralement tous les en-têtes publics d'un framework. Il s'agit généralement d'une liste d'instructions #import vers d'autres en-têtes contenus dans le framework. Dans Xcode, si vous ouvrez UIKit.h, vous verrez un bon exemple de fichier parapluie.


3
Merci pour la réponse succincte (marquée comme telle). J'avais lu cette section mais j'étais confus quant à la distinction entre l'en-tête Umbrella et Bridging.
Chris Conover

1
@ zaxy78 consultez la section "Importer Swift dans Objective-C" de ce document: developer.apple.com/library/ios/documentation/Swift/Conceptual
...

4
@DeepFriedTwinkie, de quel fichier parapluie parlez-vous quand vous dites: "Ajoutez les en-têtes nécessaires à votre fichier parapluie"? Merci.
Allan Macatingrao

2
C'est exactement ce dont j'avais besoin. Les ajouter à la section publique était le correctif.
olivaresF

20
Ai-je raison de supposer alors que toutes les classes que je veux garder privées dans mon framework qui doivent être utilisées par une classe swift doivent maintenant être rendues publiques à toute personne utilisant mon framework? Cela ne semble pas être une solution idéale.
ospr

29

Il y a deux possibilités. Ajouter les en-têtes nécessaires au fichier d'en-tête parapluie et les rendre publics est un moyen. Cependant, cela pose un problème si les en-têtes doivent être disponibles pour Swift, mais pas publics.

La deuxième possibilité qui rendra disponibles les en-têtes internes à Swift est décrite en détail ici . Essentiellement, une carte de module similaire à la suivante doit être créée:

module AwesomeKitPrivate {  
  header "../InternalClass.h"
  export *
}

Cela peut ensuite être inclus dans XCode en utilisant le paramètre:

SWIFT_INCLUDE_PATHS = $(SRCROOT)/AwesomeKit/ProjectModule  

2
Excellent! Merci. Technique bien préférée par rapport à la publication de tous les en-têtes.
David H

Déconseillons fortement cette solution aux autres, et regardez le lien fourni pour une solution détaillée
Tancrede Chazallet

C'est la bonne réponse imo, mais en fonction de ce que vous essayez de réaliser, vous pourrez peut-être vous en tirer en utilisant certaines macros fournies par Apple qui aident beaucoup avec Swift-Objc interop: developer.apple.com/documentation/swift/ …
Joe Susnick

L' headerinstruction accepte un chemin relatif. Que faites-vous lorsque vous souhaitez ajouter les en-têtes d'un autre framework?
Georgios

13

Voir Importation d'Objective-C dans Swift .

Pour importer du code Objective-C dans Swift à partir du même framework

  1. Sous Paramètres de construction, dans Empaquetage, assurez-vous que le paramètre Définit le module pour cette cible de structure est défini sur «Oui».
  2. Dans votre fichier d'en-tête parapluie, importez chaque en-tête Objective-C que vous souhaitez exposer dans Swift. Par exemple:

        #import "XYZ / XYZCustomCell.h"
        #import "XYZ / XYZCustomView.h"
        #import "XYZ / XYZCustomViewController.h"
    
  3. Rendez les fichiers inclus publics dans la section "En-têtes" du framework de ses "Phases de construction".

  4. Nettoyez et reconstruisez.

Swift verra chaque en-tête que vous exposez publiquement dans votre en-tête parapluie. Le contenu des fichiers Objective-C dans ce cadre sera disponible dans n'importe quel fichier Swift au sein de cette cible de cadre automatiquement, sans aucune instruction d'importation. Utilisez votre code Objective-C personnalisé avec la même syntaxe Swift que vous utilisez avec les classes système.

let myOtherCell = XYZCustomCell()
myOtherCell.subtitle = "Another custom cell"

Important: le "fichier d'en-tête parapluie" désigne le fichier {ModuleName} .h. BTW, le nom de la cible est {ModuleName} .framework.


1
Je veux utiliser des fichiers objc dans mon fichier Swift de modules mais je ne veux pas les exposer à d'autres modules. Comment puis-je le faire?
Sazzad Hissain Khan

0

Dans mon cas, la suppression des Objective-C Bridging Headerparamètres de mon cadre a Build Settingsaidé.

entrez la description de l'image ici

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.