Comment utiliser Swift struct en Objective-C

97

Simplement, j'ai une structure qui stocke les constantes de l'application comme ci-dessous:

struct Constant {

    static let ParseApplicationId = "xxx"
    static let ParseClientKey = "xxx"

    static var AppGreenColor: UIColor {
        return UIColor(hexString: "67B632")
    }
}

Ces constantes peuvent être utilisées en code Swift en appelant Constant.ParseClientKeypar exemple. Mais dans mon code, il contient également des classes Objective-C. Ma question est donc de savoir comment utiliser ces constantes dans le code Objective-C?

Si cette façon de déclarer des constantes n'est pas bonne, quelle est la meilleure façon de créer des constantes globales à utiliser à la fois dans le code Swift et Objective-C?

Dinh Quan
la source
22
Veuillez suivre le style de code SWIFT courant et utiliser une lettre minuscule pour commencer vos identifiants let / var.
Nikolai Ruhe
4
@NikolaiRuhe Ne serait-ce pas le style correct pour les propriétés statiques d'une structure? Un peu comme UIControlEvents.TouchUpInside?
Luke Rogers
1
@NikolaiRuhe Jetez un œil à la déclaration Swift: developer.apple.com/library/ios/documentation/UIKit/Reference/… - c'est définitivement une structure.
Luke Rogers
1
@LukeRogers C'est à cause de la nouvelle façon d'importer les NS_OPTIONSénumérations de style par Swift 2.0 . Sémantiquement UIControlEventest toujours un type d'énumération.
Nikolai Ruhe
5
@NikolaiRuhe LukeRogers: Dinh n'a pas posé de questions sur ce problème, et la plupart d'entre nous, les téléspectateurs, n'ont pas cliqué ici pour en savoir plus.
original_username

Réponses:

114

Malheureusement, vous ne pouvez pas exposer struct, ni les variables globales à Objective-C. voir la documentation .

À partir de maintenant, à mon humble avis, le meilleur moyen est quelque chose comme ceci:

let ParseApplicationId = "xxx"
let ParseClientKey = "xxx"
let AppGreenColor = UIColor(red: 0.2, green: 0.7, blue: 0.3 alpha: 1.0)

@objc class Constant: NSObject {
    private init() {}

    class func parseApplicationId() -> String { return ParseApplicationId }
    class func parseClientKey() -> String { return ParseClientKey }
    class func appGreenColor() -> UIColor { return AppGreenColor }
}

En Objective-C, vous pouvez les utiliser comme ceci:

NSString *appklicationId = [Constant parseApplicationId];
NSString *clientKey = [Constant parseClientKey];
UIColor *greenColor = [Constant appGreenColor];
Rintaro
la source
Accessible à Swift également?
khunshan
@khunshan Oui. Accessible directement ParseClientKey, ou via la classeConstant.clientKey()
Fabian
7
Devrait utiliser@objc class Constant: NSObject
William Hu
1
Cela fonctionne mais dans Swift 4, j'avais également besoin de mettre @objcdevant tout le monde class funcpour pouvoir les appeler à partir du code Objective C.
ElectroBuddha
2
@ElectroBuddha Vous pouvez faire @objcMemberssur la classe pour révéler la classe entière au code Objective-C.
user1898712
19

Pourquoi ne pas créer un fichier avec à la fois un structet un @objc class, quelque chose comme ceci:

import UIKit

extension UIColor {
    convenience init(hex: Int) {
        let components = (
            R: CGFloat((hex >> 16) & 0xff) / 255,
            G: CGFloat((hex >> 08) & 0xff) / 255,
            B: CGFloat((hex >> 00) & 0xff) / 255
        )
        self.init(red: components.R, green: components.G, blue: components.B, alpha: 1)
    }
}

extension CGColor {
    class func colorWithHex(hex: Int) -> CGColorRef {
        return UIColor(hex: hex).CGColor
    }
}

struct Constant {
    static let kParseApplicationId = "5678"
    static let kParseClientKey = "1234"
    static var kAppGreenColor: UIColor { return UIColor(hex:0x67B632) }
    static var kTextBlackColor: UIColor { return UIColor(hex:0x000000) }
    static var kSomeBgBlueColor: UIColor { return UIColor(hex:0x0000FF) }
    static var kLineGrayCGColor: CGColor { return CGColor.colorWithHex(0xCCCCCC) }
    static var kLineRedCGColor: CGColor { return CGColor.colorWithHex(0xFF0000) }
}


@objc class Constants: NSObject {
    private override init() {}

    class func parseApplicationId() -> String { return Constant.kParseApplicationId }
    class func parseClientKey() -> String { return Constant.kParseClientKey }
    class func appGreenColor() -> UIColor { return Constant.kAppGreenColor }
    class func textBlackColor() -> UIColor { return Constant.kTextBlackColor }
    class func someBgBlueColor() -> UIColor { return Constant.kSomeBgBlueColor }
    class func lineGrayCGColor() -> CGColor { return Constant.kLineGrayCGColor }
    class func lineRedCGColor() -> CGColor { return Constant.kLineRedCGColor }
}

Pour une utilisation dans les fichiers Objective-C, ajoutez ceci lorsque vous devez utiliser des constantes:

#import "ProjectModuleName-Swift.h"

Utilisation rapide:

self.view.backgroundColor = Constant.kAppGreenColor

Utilisation d'Objective-C:

self.view.backgroundColor = [Constants appGreenColor];

De cette façon, vous pouvez mettre à jour les couleurs, le texte par défaut, les URL de service Web pour toute l'application en un seul endroit.

Marijan V.
la source
1
Il n'était pas immédiatement clair pour moi que nous pouvions faire défiler votre réponse pour découvrir la partie objectif-c!
Cœur
1

Vous devez rendre les instructions let privées si vous souhaitez rendre d'autres types Swift dans votre code pour accéder à ces constantes uniquement via la classe:

private let AppGreenColor = UIColor(red: 0.2, green: 0.7, blue: 0.3 alpha: 1.0)

@objc class Constant {
    class func appGreenColor() -> UIColor { return AppGreenColor }
}

Dans Swift, vous pouvez les utiliser comme ceci:

UIColor *greenColor = Constant.appGreenColor

La ligne suivante ne se compilera plus maintenant car l'instruction let est privée:

UIColor *greenColor = appGreenColor
koira
la source
1

Bien que cela puisse être tardif ou redondant, je pourrais le faire fonctionner avec le code suivant:

@objcMembers class Flags: NSObject {
    static let abcEnabled = false
    static let pqrEnabled = false
    .
    .
    .
}

Evidemment, pour utiliser dans le code objc c, vous devez faire #import "ProjectModuleName-Swift.h"

Anil Arigela
la source