web-dev-qa-db-fra.com

Importer un protocole Swift en classe Objective-C

J'essaie d'importer un protocole Swift nommé AnalyticProtocol dans une classe Objective-C nommée AnalyticFactory.

protocol AnalyticProtocol
{

}

Je pars d'un projet Objective-C existant (je n'ai pas créé de nouveau Swift avec xCode et je n'ai pas trouvé comment configurer mon Le projet Objective-C doit être un projet Swift dans xCode 6 ).

Dans mon fichier Swift, j’ai inclus le fichier .h Nommé MyProjectName-Swift.h, Mais le compilateur m’a renvoyé une erreur en me disant que il n'existe pas . J'ai donc créé un fichier .h nommé MyProjectName-Swift.h qui est en fait vide (je ne sais pas ce que je devrais mettre à l'intérieur).

Dans le documentation Apple , ils ont dit que je devais inclure mon fichier .h Nommé MyProjectName-Swift.h Dans mon fichier .m. Mais je dois l'inclure non pas dans mon fichier .m, Mais dans mon .h. Est-ce que cela peut être problématique?

Lorsque j'essaye de compiler, j'ai l'erreur suivante: : 0: erreur: xxxAnalyticFactory.h: 39: impossible de trouver la déclaration de protocole pour 'AnalyticProtocol'

Et le code incriminé:

@interface AnalyticFactory : NSObject
{
    Class<AnalyticProtocol> _analyticProtocolClass; // The type of the analytic class currently used.
}

Je pense que je ne comprends pas bien comment importer un protocole Swift dans une classe Objective-C.

Est-ce que quelqu'un voit une erreur dans ce que je fais?

107
Jean Lebrument

Vous devez ajouter le @objc attribut à votre Swift):

@objc protocol AnalyticProtocol {

}
201
Jamie Forrest

Il n'est pas possible d'importer l'en-tête Xcode généré Swift dans les fichiers d'en-tête objC.

Donc, puisque vous voulez utiliser le code Swift dans un fichier en-tête objC, vous devrez "déclarer en aval" les classes et les protocoles que vous voulez utiliser dans le fichier en-tête objC, comme ceci:

@protocol AnalyticProtocol;

Vous pouvez maintenant utiliser le protocole dans votre déclaration de classe objC:

@interface AnalyticFactory : NSObject
{
    Class<AnalyticProtocol> _analyticProtocolClass; // The type of the analytic class currently used.
}

Dans votre fichier d'implémentation (le fichier objC .m), vous pouvez importer le fichier Xcode généré Swift en-tête ("ProductModuleName-Swift.h")) et l'implémentation correcte AnalyticProtocol maintenant être connu du compilateur.

Ceci est également décrit dans la section "Utilisation de Swift à partir d'Objective-C") dans Documents Apple

Notez que XCode donnera un avertissement dans le fichier d’en-tête objC lorsque vous utiliserez le protocole déclaré ("Impossible de trouver la définition de protocole pour 'AnalyticProtocol'), mais cela peut être ignoré - l’implémentation sera trouvée au moment de la compilation.

70

Pour quiconque ayant simplement besoin d'adopter un protocole, vous pouvez le faire en deux étapes, sans générer d'avertissements ni d'erreurs:

  1. Dans votre fichier .Swift, Ajoutez @objc Avant le nom du protocole:

    @objc protocol AnalyticProtocol {
    
    }
    
  2. Dans votre fichier .m, Importez l'en-tête généré Swift et adoptez le protocole dans une catégorie privée. (Le fichier d'en-tête est nommé automatiquement):

    #import "ProductModuleName-Swift.h"
    
    @interface AnalyticFactory () <AnalyticProtocol>
    
    @end
    

C’est l’approche recommandée par Apple. Vous pouvez en savoir plus sur le mélange et la concordance de Objective-C et Swift ici: https://developer.Apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/ MixandMatch.html

39
Chris Nolet

Si vous créez un cadre, l’importation requise

#import "ProductModuleName-Swift.h"

changements à:

#import <ProductModuleName/ProductModuleName-Swift.h>

Dans ce cas, vous devez également faire le Swift protocole public:

@objc public protocol AnalyticProtocol {
  func something();
}
1
Michal