Как использовать структуру 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 Люк Роджерс: Дин не спрашивал об этой проблеме, и большинство из нас, зрителей, не щелкали здесь, чтобы прочитать об этом.
original_username

Ответы:


114

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

На данный момент, ИМХО, лучший способ выглядит примерно так:

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];

Также доступен Swift?
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и с an @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
Мне было не сразу ясно, что мы можем прокрутить ваш ответ, чтобы узнать о части objective-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.