2017-06-30 1 views
3

J'ai plusieurs structs simples écrits dans des fichiers .swift rapides à l'intérieur. Ces structs sont très simples et contiennent presque uniquement des chaînes:Existe-t-il un moyen d'utiliser les structures Swift en Objective-C sans en faire des Classes?

struct Letter { 
    struct A { 
     static let aSome : String = "descASome" 
     static let aSomeMore : String = "descASomeMore" 
    } 
    struct B { 
     static let bNow : String = "descBNow" 
     static let bLater : String = "descBLater" 
    } 
... 
} 

Je veux utiliser ces struct dans un projet qui contient du code Objective-C parce que j'écris un cadre multi-plateforme.

J'ai lu: ObjectiveC - Swift interoperability by Apple qui stipule clairement que struct Swift écrit ne peuvent pas être utilisés par ObjectiveC. Sont exclus les (entre autres fonctions):

Structures définies dans Swift

Solution 1:

J'ai trouvé une solution SO qui résout le problème en utilisant des classes:

@objc class Letter : NSObject { 
    @objc class A : NSObject { 
     static let aSome : String = "descASome" 
     static let aSomeMore : String = "descASomeMore" 
    } 
    @objc class B : NSObject { 
     static let bNow : String = "descBNow" 
     static let bLater : String = "descBLater" 
    } 
... 
} 

Cette solution fonctionne, mais je dois réécrire tous les structs t o cours. Ils ne sont pas non plus légers comme des structures (entre autres choses). En plus je me sens comme si je revenais en arrière pour résoudre le problème.

Q1. Existe-t-il un autre moyen d'utiliser les structures Swift à l'intérieur de ObjectiveC à côté de la solution 1, qui ne convient pas bien à mon projet/situation? (Énumérations peuvent être utilisées si elles sont rawValue Int)

Q2. Y at-il un moyen d'utiliser #define SomeConst pour l'accès et ObjectiveC stucts pour l'accès Swift comme:

#if macOS // if Swift? 
#endif 
+1

Votre Q1 est un duplicata de https://stackoverflow.com/questions/26173234/how-to-use-swift-struct-in-objective-c. Il est documenté * que les structures Swift ne sont pas importées dans Objective-C. –

+0

Je pourrais éditer la question mais la réponse était "dès maintenant" - 2014 ... la solution n'est pas très bonne pour mon cas (grosse application). – Darkwonder

+0

Si vous savez * "que les structures écrites de Swift ne peuvent pas être utilisées par ObjectiveC" * alors demandez-vous * "Y at-il un moyen d'utiliser les structures Swift dans ObjectiveC?" * –

Répondre

1

Vous ne pouvez pas faire cela sans faire quelques ré-écriture: struct Swift ne sont tout simplement pas visible de ObjC.

Vous devez écrire un ObjC visible classe Swift pour exposer les valeurs, en quelque sorte l'inverse des types « overlay » de Swift Foundation.

Une option consiste à suivre aussi étroitement que possible la structure du code Swift. Notez que les classes imbriquées ne sont pas acceptées et que le "overlay" ObjC doit avoir un nom différent de celui de la structure Swift. C'est regrettable mais impossible à contourner, puisque ce code Swift est visible aux mêmes endroits que la structure originale.

importation Fondation

@objc class OCLetters : NSObject { 
    static let A = _A.self 
    static let B = _B.self 
} 

@objc class _A : NSObject { 
    static let some = Letters.A.some 
    static let someMore = Letters.A.someMore 
} 

@objc class _B : NSObject { 
    static let now = Letters.B.now 
    static let later = Letters.B.later 
} 

Si vous voulez utiliser la notation de points pour les valeurs de votre cependant, le code de ObjC, cela ne fonctionnera pas. C'est probablement un bogue, mais le .some dans OCLetters.A.some est traité comme une référence de membre struct, qui échoue. (La modification des propriétés en propriétés de classe calculées ne fonctionne pas non plus.) Vous devez écrire [[OCLetters A] some] (ou [OCLetters.A some]).

Pour pouvoir utiliser la notation de points, vous devez changer la structure légèrement de sorte que les propriétés sont en fait des cas:

import Foundation 

@objc class OCLetters : NSObject { 
    static let A = _A() 
    static let B = _B() 
} 

@objc class _A : NSObject { 
    let some = Letters.A.some 
    let someMore = Letters.A.someMore 
} 

@objc class _B : NSObject { 
    let now = Letters.B.now 
    let later = Letters.B.later 
} 

Notez également que vous ne pouvez malheureusement pas limiter la visibilité dans ObjC de les classes auxiliaires _A et _B, car si elles ne sont pas visibles, les propriétés de OCLetters ne le seront pas non plus.