Jak korzystać ze struktury Swift w Objective-C

97

Po prostu mam strukturę, która przechowuje stałe aplikacji, jak poniżej:

struct Constant {

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

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

Te stałe mogą być używane w kodzie Swift, wywołując Constant.ParseClientKeyna przykład. Ale w moim kodzie zawiera również kilka klas Objective-C. Więc moje pytanie brzmi: jak używać tych stałych w kodzie Objective-C?

Jeśli ten sposób deklarowania stałych nie jest dobry, to jaki jest najlepszy sposób tworzenia globalnych stałych, które będą używane zarówno w kodzie Swift, jak i Objective-C?

Dinh Quan
źródło
22
Postępuj zgodnie z popularnym stylem szybkiego kodu i użyj małej litery, aby rozpocząć identyfikatory let / var.
Nikolai Ruhe
4
@NikolaiRuhe Czy nie byłby to właściwy styl dla statycznych właściwości struktury? Bardzo jak UIControlEvents.TouchUpInside?
Luke Rogers
1
@NikolaiRuhe Spójrz na deklarację Swift: developer.apple.com/library/ios/documentation/UIKit/Reference/ ... - to zdecydowanie struktura.
Luke Rogers
1
@LukeRogers Dzieje się tak ze względu na zmieniony sposób importowania wyliczeń stylów w Swift 2.0 NS_OPTIONS. Semantycznie UIControlEventjest nadal typem wyliczenia.
Nikolai Ruhe
5
@NikolaiRuhe LukeRogers: Dinh nie pytał o ten problem, a większość z nas, widzów, nie kliknęła tutaj, aby o tym przeczytać.
original_username

Odpowiedzi:

114

Niestety, nie można wystawiać structani zmiennych globalnych na Objective-C. zobacz dokumentację .

Jak na razie IMHO, najlepszym sposobem jest coś takiego:

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

W Objective-C możesz ich używać w następujący sposób:

NSString *appklicationId = [Constant parseApplicationId];
NSString *clientKey = [Constant parseClientKey];
UIColor *greenColor = [Constant appGreenColor];
rintaro
źródło
Dostępny także dla Swift?
khunshan
@khunshan Yes. Dostępne bezpośrednio ParseClientKeylub przez zajęciaConstant.clientKey()
Fabian
7
Powinien użyć@objc class Constant: NSObject
William Hu
1
To działa, ale w Swift 4 musiałem również umieścić je @objcprzed każdym, class funcaby móc wywołać je z kodu Objective C.
ElectroBuddha
2
@ElectroBuddha Możesz zrobić @objcMembersna klasie, aby ujawnić całą klasę kodowi Objective-C.
user1898712
19

Dlaczego nie utworzyć pliku zawierającego zarówno a, jak structi an @objc class, coś takiego:

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

Do użytku w plikach Objective-C dodaj to, gdy potrzebujesz użyć stałych:

#import "ProjectModuleName-Swift.h"

Szybkie użycie:

self.view.backgroundColor = Constant.kAppGreenColor

Zastosowanie obiektywu C:

self.view.backgroundColor = [Constants appGreenColor];

W ten sposób możesz zaktualizować kolory, domyślny tekst, adresy URL usług internetowych dla całej aplikacji w jednym miejscu.

Marijan V.
źródło
1
Nie było dla mnie od razu jasne, że możemy przewinąć twoją odpowiedź, aby odkryć część dotyczącą celu!
Cœur
1

Powinieneś ustawić instrukcje let jako prywatne, jeśli chcesz, aby inne typy Swift w swoim kodzie miały dostęp do tych stałych tylko za pośrednictwem klasy:

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

W Swift możesz ich używać w następujący sposób:

UIColor *greenColor = Constant.appGreenColor

Następująca linia nie będzie się już kompilować, ponieważ instrukcja let jest prywatna:

UIColor *greenColor = appGreenColor
koira
źródło
1

Chociaż może to być spóźnione lub zbędne, mogę sprawić, że zadziała z następującym kodem:

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

Oczywiście, aby użyć kodu objc c, musisz wykonać #import „ProjectModuleName-Swift.h”

Anil Arigela
źródło