Verwendung der Swift-Struktur in Objective-C


97

Ich habe einfach eine Struktur, die die Anwendungskonstanten wie folgt speichert:

struct Constant {

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

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

Diese Konstanten können im Swift-Code beispielsweise durch Aufrufen verwendet werden Constant.ParseClientKey. In meinem Code enthält es jedoch auch einige Objective-C-Klassen. Meine Frage ist also, wie diese Konstanten im Objective-C-Code verwendet werden sollen.

Wenn diese Art der Deklaration von Konstanten nicht gut ist, wie lassen sich dann globale Konstanten am besten erstellen, die sowohl im Swift- als auch im Objective-C-Code verwendet werden können?


22
Bitte folgen Sie dem üblichen schnellen Codestil und verwenden Sie einen Kleinbuchstaben, um Ihre let / var-Bezeichner zu starten.
Nikolai Ruhe

4
@NikolaiRuhe Wäre dies nicht der richtige Stil für statische Eigenschaften einer Struktur? Ähnlich wie UIControlEvents.TouchUpInside?
Luke Rogers

1
@NikolaiRuhe Schauen Sie sich die Swift-Deklaration an: developer.apple.com/library/ios/documentation/UIKit/Reference/… - es ist definitiv eine Struktur.
Luke Rogers

1
@LukeRogers Das liegt an Swift 2.0s geänderter Art, NS_OPTIONSStil-Enums zu importieren . Semantisch UIControlEventist immer noch ein Aufzählungstyp.
Nikolai Ruhe

5
@NikolaiRuhe LukeRogers: Dinh hat nicht nach diesem Thema gefragt, und die meisten von uns Zuschauern haben hier nicht geklickt, um darüber zu lesen.
original_username

Antworten:


114

Leider können Sie weder structObjective-C noch globale Variablen für Objective-C verfügbar machen. siehe die Dokumentation .

Ab sofort, IMHO, ist der beste Weg so etwas:

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 können Sie sie folgendermaßen verwenden:

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

Auch für Swift zugänglich?
Khunshan

@ Khunshan Ja. Erreichbar direkt ParseClientKeyoder über die KlasseConstant.clientKey()
Fabian

7
Sollte verwenden@objc class Constant: NSObject
William Hu

1
Dies funktioniert, aber in Swift 4 musste ich auch @objcvor jeden stellen class func, um sie aus Objective C-Code aufrufen zu können.
ElectroBuddha

2
@ElectroBuddha Sie können @objcMembersfür die Klasse die gesamte Klasse für Objective-C-Code anzeigen .
user1898712

19

Warum nicht eine Datei sowohl mit einem erstellen structund eine @objc class, etwas wie folgt aus :

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

Fügen Sie dies zur Verwendung in Objective-C-Dateien hinzu, wenn Sie Konstanten verwenden müssen:

#import "ProjectModuleName-Swift.h"

Schnelle Nutzung:

self.view.backgroundColor = Constant.kAppGreenColor

Objective-C-Nutzung:

self.view.backgroundColor = [Constants appGreenColor];

Auf diese Weise können Sie Farben, Standardtext und Webdienst-URLs für die gesamte App an einem Ort aktualisieren.


1
Mir war nicht sofort klar, dass wir Ihre Antwort scrollen können, um den objektiven Teil zu entdecken!
Cœur

1

Sie sollten die let-Anweisungen privat machen, wenn Sie andere Swift-Typen in Ihrem Code erstellen möchten, um nur über die Klasse auf diese Konstanten zuzugreifen:

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 können Sie sie folgendermaßen verwenden:

UIColor *greenColor = Constant.appGreenColor

Die folgende Zeile wird jetzt nicht mehr kompiliert, da die let-Anweisung privat ist:

UIColor *greenColor = appGreenColor

1

Obwohl dies zu spät oder überflüssig sein könnte, könnte ich es mit dem folgenden Code zum Laufen bringen:

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

Um in objc c Code zu verwenden, müssen Sie natürlich #import "ProjectModuleName-Swift.h" ausführen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.