Як використовувати структуру Swift у Objective-C


97

Просто у мене є структура, яка зберігає константи програми, як показано нижче:

struct Constant {

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

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

Ці константи можна використовувати в коді Swift, наприклад, викликаючи Constant.ParseClientKey. Але в моєму коді він також містить кілька класів Objective-C. Тож моє запитання - як використовувати ці константи в коді Objective-C?

Якщо такий спосіб оголошення констант не є добрим, то який найкращий спосіб створити глобальні константи, які використовуватимуться як у коді Swift, так і в Objective-C?


22
Будь ласка, дотримуйтесь поширеного стилю швидкого коду та використовуйте малу літеру, щоб розпочати ідентифікатори let / var.
Микола Руе

4
@NikolaiRuhe Чи не буде це правильним стилем для статичних властивостей структури? Багато чого UIControlEvents.TouchUpInside?
Люк Роджерс

1
@NikolaiRuhe Погляньте на декларацію Swift: developer.apple.com/library/ios/documentation/UIKit/Reference/… - це, безумовно, структура.
Люк Роджерс

1
@LukeRogers Це через змінений спосіб Swift 2.0, як імпортувати NS_OPTIONSпереліки стилів. Семантично UIControlEventвсе ще є типом перерахування.
Микола Руе

5
@NikolaiRuhe LukeRogers: Дінь не запитував про це питання, і більшість із нас, глядачі, не натискали тут, щоб прочитати про це.
original_username

Відповіді:


114

Як це не сумно говорити, ви не можете виставити struct, ні глобальні змінні для Objective-C. дивіться документацію .

На сьогоднішній день, IMHO, найкращий спосіб - приблизно такий:

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

У Objective-C ви можете використовувати їх так:

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

Також доступний Свіфт?
khunshan

@khunshan Так. Доступний безпосередньо ParseClientKeyабо через класConstant.clientKey()
Фабіан

7
Потрібно використовувати@objc class Constant: NSObject
Вільям Ху

1
Це працює, але в Swift 4 мені також потрібно було поставити @objcперед кожним, class funcщоб мати можливість викликати їх із коду Objective C.
ElectroBuddha

2
@ElectroBuddha Ви можете зробити @objcMembersв класі, щоб показати весь клас коду Objective-C.
user1898712

19

Чому б не створити файл як з a, так structі @objc classприблизно так:

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

Для використання у файлах Objective-C додайте це, коли потрібно використовувати константи:

#import "ProjectModuleName-Swift.h"

Швидке використання:

self.view.backgroundColor = Constant.kAppGreenColor

Використання Objective-C:

self.view.backgroundColor = [Constants appGreenColor];

Таким чином ви можете в одному місці оновлювати кольори, текст за замовчуванням, URL-адреси веб-сервісу для всієї програми.


1
Мені не одразу було ясно, що ми можемо прокрутити вашу відповідь, щоб виявити частину-c!
Cœur,

1

Ви повинні зробити оператори let приватними, якщо хочете зробити у своєму коді інші типи Swift для доступу до цих констант лише за допомогою класу:

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

У Swift ви можете використовувати їх так:

UIColor *greenColor = Constant.appGreenColor

Наступний рядок більше не компілюється, оскільки оператор let є приватним:

UIColor *greenColor = appGreenColor

1

Хоча це може бути запізненням або зайвим, я міг би змусити його працювати з таким кодом:

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

Очевидно, що для використання в коді objc c вам потрібно зробити #import "ProjectModuleName-Swift.h"

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.