Come usare Swift struct in Objective-C


97

Semplicemente ho una struttura che memorizza le costanti dell'applicazione come di seguito:

struct Constant {

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

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

Queste costanti possono essere utilizzate nel codice Swift chiamando Constant.ParseClientKeyad esempio. Ma nel mio codice contiene anche alcune classi Objective-C. Quindi la mia domanda è come utilizzare queste costanti nel codice Objective-C?

Se questo modo di dichiarare le costanti non è buono, qual è il modo migliore per creare costanti globali da utilizzare sia nel codice Swift che in quello Objective-C?


22
Segui lo stile del codice swift comune e utilizza una lettera minuscola per iniziare gli identificatori let / var.
Nikolai Ruhe

4
@NikolaiRuhe Non sarebbe questo lo stile corretto per le proprietà statiche di una struttura? Molto simile UIControlEvents.TouchUpInside?
Luke Rogers

1
@NikolaiRuhe Dai un'occhiata alla dichiarazione Swift: developer.apple.com/library/ios/documentation/UIKit/Reference/… - è sicuramente una struttura.
Luke Rogers

1
@LukeRogers Questo è dovuto al modo cambiato di Swift 2.0 di importare NS_OPTIONSenumerazioni di stile. Semanticamente UIControlEventè ancora un tipo di enumerazione.
Nikolai Ruhe

5
@NikolaiRuhe LukeRogers: Dinh non ha chiesto informazioni su questo problema e la maggior parte di noi spettatori non ha fatto clic qui per leggere.
original_username

Risposte:


114

Triste a dirsi, non puoi esporre struct, né le variabili globali a Objective-C. vedere la documentazione .

A partire da ora, IMHO, il modo migliore è qualcosa del genere:

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 }
}

In Objective-C, puoi usarli in questo modo:

NSString *appklicationId = [Constant parseApplicationId];
NSString *clientKey = [Constant parseClientKey];
UIColor *greenColor = [Constant appGreenColor];

Accessibile anche a Swift?
khunshan

@khunshan Sì. Accessibile direttamente ParseClientKeyo tramite la classeConstant.clientKey()
Fabian

7
Dovrebbe usare@objc class Constant: NSObject
William Hu

1
Funziona ma in Swift 4, dovevo anche metterli @objcdavanti a tutti class funcper poterli chiamare dal codice Objective C.
ElectroBuddha

2
@ElectroBuddha Puoi fare @objcMembersin classe per rivelare l'intera classe al codice Objective-C.
user1898712

19

Perché non creare un file con sia un structche un @objc class, qualcosa del genere:

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 }
}

Per l'uso nei file Objective-C, aggiungi questo quando devi usare le costanti:

#import "ProjectModuleName-Swift.h"

Utilizzo rapido:

self.view.backgroundColor = Constant.kAppGreenColor

Utilizzo di Objective-C:

self.view.backgroundColor = [Constants appGreenColor];

In questo modo puoi aggiornare i colori, il testo predefinito, gli URL del servizio web per l'intera app in un unico posto.


1
Non mi è stato subito chiaro che avremmo potuto scorrere la tua risposta per scoprire la parte obiettivo-c!
Cœur

1

Dovresti rendere private le istruzioni let se vuoi rendere altri tipi di Swift nel tuo codice per accedere a queste costanti solo tramite class:

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 }
}

In Swift, puoi usarli in questo modo:

UIColor *greenColor = Constant.appGreenColor

La riga seguente non verrà più compilata ora poiché l'istruzione let è privata:

UIColor *greenColor = appGreenColor

1

Anche se questo potrebbe essere in ritardo o ridondante, potrei farlo funzionare con il seguente codice:

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

Ovviamente, per usarlo nel codice objc c, devi fare #import "ProjectModuleName-Swift.h"

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.