web-dev-qa-db-fra.com

Comment appeler le code Objective-C depuis Swift?

Dans Swift, comment appelle-t-on le code Objective-C?

Apple a mentionné qu'ils pourraient coexister dans une application, mais cela signifie-t-il que l'on pourrait réutiliser techniquement les anciennes classes créées dans Objective-C lors de la construction de nouvelles classes dans Swift?

920
David Mulder

Utilisation de classes Objective-C dans Swift

** Si vous souhaitez utiliser une classe existante, effectuez Étape 2 puis passez à Étape 5. (Dans certains cas, j'ai dû ajouter un #import <Foundation/Foundation.h explicite à un fichier Objective-C plus ancien.) **

Étape 1: Ajouter une implémentation d'Objective-C - .m

Ajoutez un fichier .m à votre classe et nommez-le CustomObject.m.

Étape 2: Ajouter un en-tête de pontage

Lorsque vous ajoutez votre fichier .m, vous serez probablement frappé par une invite qui ressemble à ceci:

Enter image description here

Cliquez sur OUI !

Si vous n'avez pas vu l'invite ou si vous avez supprimé accidentellement votre en-tête de pontage, ajoutez un nouveau fichier .h à votre projet et nommez-le <#YourProjectName#>-Bridging-Header.h.

Dans certaines situations, notamment lorsque vous travaillez avec des infrastructures Objective-C, vous n’ajoutez pas explicitement une classe Objective-C et Xcode ne peut pas trouver l’éditeur de liens. Dans ce cas, créez votre fichier .h nommé comme indiqué ci-dessus, puis assurez-vous de lier son chemin d'accès dans les paramètres de projet de votre cible, comme suit:

Enter image description here

Remarque

Il est recommandé de lier votre projet à l'aide de la macro $(SRCROOT) afin que, si vous déplacez votre projet ou travaillez avec d'autres personnes à l'aide d'un référentiel distant, il fonctionnera toujours. $(SRCROOT) peut être considéré comme le répertoire contenant votre fichier .xcodeproj. Cela pourrait ressembler à ceci:

$(SRCROOT)/Folder/Folder/<#YourProjectName#>-Bridging-Header.h

Étape 3: Ajouter un en-tête Objective-C - .h

Ajoutez un autre fichier .h et nommez-le CustomObject.h.

Étape 4: Construisez votre classe Objective-C

Dans CustomObject.h

#import <Foundation/Foundation.h>

@interface CustomObject : NSObject

@property (strong, nonatomic) id someProperty;

- (void) someMethod;

@end

Dans CustomObject.m

#import "CustomObject.h"

@implementation CustomObject 

- (void) someMethod {
    NSLog(@"SomeMethod Ran");
}

@end

Étape 5: Ajouter une classe à un en-tête de pontage

Dans YourProject-Bridging-Header.h:

#import "CustomObject.h"

Étape 6: Utilisez votre objet

Dans SomeSwiftFile.Swift:

var instanceOfCustomObject: CustomObject = CustomObject()
instanceOfCustomObject.someProperty = "Hello World"
println(instanceOfCustomObject.someProperty)
instanceOfCustomObject.someMethod()

Il n'est pas nécessaire d'importer explicitement. c'est à cela que sert l'en-tête de pontage.

Utilisation de Swift Classes dans Objective-C

Étape 1: Créer une nouvelle classe Swift

Ajoutez un fichier .Swift à votre projet et nommez-le MySwiftObject.Swift.

Dans MySwiftObject.Swift:

import Foundation

class MySwiftObject : NSObject {

    var someProperty: AnyObject = "Some Initializer Val"

    init() {}

    func someFunction(someArg:AnyObject) -> String {
        var returnVal = "You sent me \(someArg)"
        return returnVal
    }   
}

Étape 2: Importer Swift Fichiers dans la classe ObjC

Dans SomeRandomClass.m:

#import "<#YourProjectName#>-Swift.h"

Le fichier: <#YourProjectName#>-Swift.h devrait déjà être créé automatiquement dans votre projet, même si vous ne le voyez pas.

Étape 3: Utilisez votre classe

MySwiftObject * myOb = [MySwiftObject new];
NSLog(@"MyOb.someProperty: %@", myOb.someProperty);
myOb.someProperty = @"Hello World";
NSLog(@"MyOb.someProperty: %@", myOb.someProperty);

// original
NSString * retString = [myOb someFunction:@"Arg"];
// xcode10 expands the external arg here
NSString * retString = [myOb someFunctionWithSomeArg:@"Arg"];|

NSLog(@"RetString: %@", retString);

Remarque:

1. CodeCompletion ne se comportait pas aussi précisément que je le voudrais. Sur mon système, exécuter une construction rapide avec "cmd + r" semblait aider Swift à trouver une partie du code Objective-C et inversement.

2. Si vous ajoutez un fichier .Swift à un projet plus ancien et obtenez l'erreur: dyld: Library not loaded: @rpath/libswift_stdlib_core.dylib, essayez complètement redémarrage de Xcode .

3. Alors qu'il était à l'origine possible d'utiliser des classes Swift pures dans Objective-C en utilisant le préfixe @objc, après Swift 2.0, cela n'est plus possible. Voir l'historique d'édition pour l'explication originale. Si cette fonctionnalité est réactivée dans les futures versions Swift, la réponse sera mise à jour en conséquence.

1329
Logan

Consultez le guide Apple intitulé tilisation de Swift avec Cocoa et Objective-C . Ce guide explique comment utiliser les codes Objective-C et C à partir de Swift et vice versa, et contient des recommandations sur la conversion d'un projet ou la combinaison d'éléments Objective-C/C et Swift. dans un projet existant.

Le compilateur génère automatiquement la syntaxe Swift pour l'appel des fonctions C et des méthodes Objective-C. Comme on le voit dans la documentation, cet Objective-C:

UITableView *myTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];

se transforme en ce code Swift:

let myTableView: UITableView = UITableView(frame: CGRectZero, style: .Grouped)

Xcode effectue également cette traduction à la volée - vous pouvez utiliser Ouvrir rapidement lors de la modification d'un fichier Swift et taper un nom de classe Objective-C. . (Vous pouvez également l'obtenir en cliquant sur cmd en cliquant sur un symbole d'API dans un fichier Swift.) Et toute la documentation de référence d'API dans iOS 8 et OS X Les bibliothèques de développement v10.10 (Yosemite) sont visibles sous les formes Objective-C et Swift (par exemple, UIView ).

116
rickster

Voici des instructions pas à pas pour utiliser le code Objective-C (dans ce cas, une structure fournie par un tiers) dans un projet Swift:

  1. Ajoutez n'importe quel fichier Objective-C à votre projet Swift en choisissant Fichier -> Nouveau -> Nouveau fichier -> Fichier Objective-C . Lors de la sauvegarde, Xcode vous demandera si vous souhaitez ajouter un en-tête de pontage . Choisissez ' Oui '. Gif: ajout d'un fichier vide au projet et génération d'un en-tête de pontage http://www.derrrick.com/stackoverflow/1-empty-file.gif

En étapes simples:

  1. Une invite apparaît, puis cliquez sur OK ... S'il n'apparaît pas, nous le créons manuellement comme suit: Créez un fichier d'en-tête à partir de la source iOS et donnez le nom ProjectName-Bridging-Header (exemple: Test -Bridging-Header), puis accédez au paramètre de construction dans le Swift code du compilateur -> Le pont Objective-C ajoute le nom du pont Objective-C .. (Test/Test-Bridging-Header.h). Oui, c'est complet.

  2. Supprimez éventuellement le fichier Objective-C que vous avez ajouté (nommé "rien" dans l'image GIF ci-dessus). Vous n'en avez plus besoin.

  3. Ouvrez le fichier d'en-tête de pontage - le nom du fichier est de la forme [Votre projet] -Bridging-Header.h . Il inclut un commentaire fourni par Xcode. Ajoutez une ligne de code pour le fichier Objective-C que vous souhaitez inclure , tel qu'un framework tiers. Par exemple, pour ajouter Mixpanel à votre projet, vous devez ajouter la ligne de code suivante au fichier d’en-tête de pontage:

    #import "Mixpanel.h"
  4. Maintenant, dans tout fichier Swift, vous pouvez utiliser le code Objective-C existant, dans la syntaxe Swift (en le cas de cet exemple, et vous pouvez appeler les méthodes Mixpanel SDK, etc.). Vous devez vous familiariser avec la façon dont Xcode traduit Objective-C en Swift. Guide Apple est une lecture rapide. Ou voyez cette réponse pour un résumé incomplet.

Exemple pour Mixpanel:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    Mixpanel.sharedInstanceWithToken("your-token")
    return true
}

C'est ça!

Remarque: Si vous supprimez le fichier d'en-tête de pontage de votre projet , veillez à accéder à Paramètres de construction et à supprimer la valeur de " En-tête de pontage Objective-C "sous" Compilateur Swift - Génération de code ".

59
derrrick

Vous pouvez lire le post de Nice Swift & Cocoapods. En gros, nous devons créer un fichier d’en-tête de pontage et y placer tous les en-têtes Objective-C. Et nous devons ensuite le référencer à partir de nos paramètres de construction. Après cela, nous pouvons utiliser le code Objective-C.

let manager = AFHTTPRequestOperationManager()
manager.GET(
  "http://example.com/resources.json",
  parameters: nil,
  success: { (operation: AFHTTPRequestOperation!,
              responseObject: AnyObject!) in
      println("JSON: " + responseObject.description)
  },
  failure: { (operation: AFHTTPRequestOperation!,
              error: NSError!) in
      println("Error: " + error.localizedDescription)
  })

Consultez également le document d'Apple tilisation de Swift avec Cocoa et Objective-C.

38
Jake Lin

J'ai écrit un simple projet Xcode 6 qui montre comment mélanger du code C++, Objective-C et Swift:

https://github.com/romitagl/shared/tree/master/C-ObjC-Swift/Performance_Console

En particulier, l'exemple appelle une fonction Objective-C et une fonction C++ à partir de Swift .

La clé est de créer un en-tête partagé, Project-Bridging-Header.h, et d'y placer les en-têtes Objective-C.

Veuillez télécharger le projet comme exemple complet.

24
Gian Luigi Romita

Citation de la documentation :

Tout framework Objective-C (ou bibliothèque C) accessible en tant que module peut être importé directement dans Swift. Cela inclut tous les frameworks système Objective-C (tels que Foundation, UIKit et SpriteKit) ainsi que les bibliothèques C communes fournies avec le système. Par exemple, pour importer Foundation, ajoutez simplement cette instruction d'importation en haut du fichier Swift dans lequel vous travaillez:

import Foundation

Grâce à cette importation, toutes les API Foundation (y compris NSDate, NSURL, NSMutableData et toutes leurs méthodes, propriétés et catégories) sont directement disponibles dans Swift.

21
Gergo Erdosi

Une dernière chose que j'aimerais ajouter ici:

Je suis très reconnaissant pour la réponse de @ Logan. Il est très utile de créer un fichier pont et des configurations.

Mais après toutes ces étapes, je ne reçois toujours pas de cours Objective-C à Swift.

J'ai utilisé la bibliothèque cocoapods et l'ai intégrée à mon projet. Qui est pod "pop".

Donc, si vous utilisez des modules Objective-C dans Swift, il se peut que vous ne puissiez pas obtenir ou import les classes dans Swift.

La chose simple à faire est de:

  1. Allez dans le fichier <YOUR-PROJECT>-Bridging-Header et
  2. Remplacez l'instruction #import <ObjC_Framework> par @import ObjC_Framework

Par exemple: (bibliothèque Pop)

Remplacer

#import <pop/POP.h>

avec

@import pop;

Utilisez clang import lorsque #import ne fonctionne pas.

20
Kampai

Juste une note pour ceux qui essaient d’ajouter une bibliothèque Objective-C à Swift: Vous devriez ajouter - ObjC dans Configurer les paramètres -> Liaison -> Autres drapeaux de l'éditeur de liens .

11
david72

Après avoir créé un en-tête de pontage, allez à Build Setting => recherchez "Header de pontage Objective-C".

Vous trouverez ci-dessous le fichier "" Nom d'en-tête d'interface généré par Objective-C ".

Importez ce fichier dans votre contrôleur de vue.

Exemple: Dans mon cas: "Dauble-Swift.h"

eEter image description here

8
Avijit Nagare

Cliquez sur le menu Nouvea fichier, puis choisissez la langue de sélection de fichier Objectif. À ce moment, il génère automatiquement un fichier "Objective-C Bridging Header" utilisé pour définir un nom de classe.

"En-tête de pontage Objective-C" sous "Compilateur Swift - Génération de code".

4
Yogesh shelke
  1. Créez un fichier .h à partir de NewFile -> Source -> fichier d’en-tête
  2. Enregistrez ensuite le nom du fichier Your_Target_Name-Bridging-Header.h Ici, les gens commettent une erreur commune en prenant le nom de leur projet, mais il devrait s'agir du nom de la cible du projet si les deux sont différents, ils sont généralement identiques.
  3. Ensuite, dans les paramètres de construction, recherchez En-tête de pontage Objective-C et mettez l’adresse de votre fichier de pontage nouvellement créé, vous pouvez le faire un clic droit sur le fichier -> afficher dans le Finder -> faire glisser le fichier dans la zone de texte alors l'adresse sera remplie.
  4. Utilisation de #import Your_Objective-C_file.h
  5. Dans le fichier Swift, vous pouvez accéder au fichier ObjC mais uniquement dans la langue Swift.
3
Nish

enter image description here J'ai ajouté le projet sur github qui inclut un petit échantillon pour appeler le code Objective C depuis Swift.

appelez la classe ObjectiveC de Swift

3
CrazyPro007

Dans le projet Swift 4.2.1 de Xcode 10.1, vous pouvez facilement ajouter un fichier Objective-C. Suivez les étapes ci-dessous pour relier le fichier Objective-C au projet Swift.

Étape_01: Créer un nouveau projet Xcode en utilisant Swift langue:

File> New> Project> objc.

Step_02: Dans le projet Swift, ajoutez un nouveau fichier Objective-C:

File> New> File...> macOS> Objective-C File.

Step_03: Si vous ajoutez un nouveau fichier Objective-C dans le projet Swift au tout début, Xcode vous demande:

Would you like to configure an Objective-C bridging header?

enter image description here

Step_04: Sélectionnez l'option:

Create Bridging Header.

Step_05: Un fichier correspondant sera généré avec un nom:

Objc-Bridging-Header.h.

enter image description here

Step_06: Vous devez maintenant configurer le chemin du fichier Bridge dans son en-tête. Dans Project Navigator, cliquez sur le projet nommé objc, puis choisissez:

Build Settings> Objective-C Bridging Header> Objc-Bridging-Header.h.

Step_07: Glissez-déposez votre Objc-Bridging-Header.h dans cette zone pour générer un chemin de fichier.

enter image description here

Step_08: Ouvrez votre fichier Objc-Bridging-Header.h et importez le fichier Objective-C que vous souhaitez utiliser dans votre fichier Swift.

#import "SpecialObjcFile.m"

Voici un contenu de SpecialObjcFile.m:

#import <Foundation/Foundation.h>

@interface Person: NSObject {
@public
    bool busy;
}
@property
    bool busy;
@end

Step_09: Dans votre fichier Swift, vous pouvez utiliser une classe Objective-C:

override func viewDidLoad() {
    super.viewDidLoad()
    let myObjcContent = Person()
    print(myObjcContent.busy)
}

enter image description hereenter image description here

2
ARGeo

Utilisation de classes Objective-C dans Swift

  1. Ajouter l'en-tête Objective-C .h et l'implémentation .m
    Ajoutez les fichiers <FileName>.m et <FileName>.h à votre projet.

  2. Ajouter un en-tête de pontage
    Lors de l'ajout de votre fichier .m, cliquez sur "Oui" à l'invite Would you like to configure an Objective-C bridging header

  3. Ajouter une classe à un en-tête de pontage
    Dans YourProject-Bridging-Header.h ajoutez une ligne #import "<FileName>.h"

Utilisation de Swift Classes en Objective-C

  1. Ajouter un fichier <FileName>.Swift qui étend NSObject à votre projet
  2. Importer Swift Fichiers dans la classe ObjC
    Ajoutez #import "<#YourProjectName#>-Swift.h" dans votre fichier Objective-C
  3. Mark public Swift code [@objc et @objcMembers]

Lire la suite ici

1
yoAlex5

Approche à deux sens pour utiliser objectif-c objectif-c

1

  1. Créer un fichier bridge-header.h dans le projet Xcode
  2. importer un fichier .h dans le fichier bridge-Header
  3. Définissez le chemin de l'en-tête de pont dans les paramètres de construction.
  4. Nettoyer le projet

2

  1. Créer des fichiers objective-c dans le projet (il définit automatiquement le chemin dans les paramètres de construction pour vous)
  2. importer un fichier .h dans le fichier bridge-Header

Bon maintenantMerci

0
Sanjay Mali

Apple a fourni un guide officiel dans cette doc: comment-appeler-objectif-c-code-de-Swift

Voici la partie pertinente:

Pour importer un ensemble de fichiers Objective-C dans le code Swift au sein de la même cible d'application, vous comptez sur un fichier d'en-tête de pontage Objective-C . pour exposer ces fichiers à Swift . Xcode vous propose de créer cet en-tête lorsque vous ajoutez un fichier Swift à une application Objective-C existante, ou un fichier Objective-C à une application Swift existante.

Si vous acceptez, Xcode crée le fichier d'en-tête de pontage avec le fichier que vous étiez en train de créer et nommez-le en utilisant le nom du module de votre produit suivi de "-Bridging-Header.h". Vous pouvez également créer vous-même un en-tête de pontage en choisissant Fichier> Nouveau> Fichier> [système d'exploitation]> Source> Fichier d'en-tête .

Editez l'en-tête de pontage pour exposer votre code Objective-C à votre code Swift:

  1. Dans votre en-tête de pontage Objective-C, importez chaque en-tête Objective-C que vous souhaitez exposer à Swift .
  2. Dans les paramètres de construction, dans Swift Compilateur - Génération de code, assurez-vous que le paramètre de construction En-tête de pontage Objective-C comporte un chemin d'accès au fichier d'en-tête de pontage. Le chemin doit être relatif à votre projet, de la même manière que votre chemin Info.plist est spécifié dans les paramètres de construction. Dans la plupart des cas, il n'est pas nécessaire de modifier ce paramètre.

Tous les en-têtes publics Objective-C répertoriés dans l'en-tête de pontage sont visibles pour Swift.

0
Tibin Thomas

Logans answer fonctionne très bien, sauf dans le dernier Swift 5 il génère des erreurs de compilation. Voici le correctif pour les personnes qui travaillent sur Swift 5.

Swift 5

import Foundation

class MySwiftObject : NSObject {

    var someProperty: AnyObject = "Some Initializer Val" as AnyObject

    override init() {}

    func someFunction(someArg:AnyObject) -> String {
        let returnVal = "You sent me \(someArg)"
        return returnVal
    }
}
0