Различия между двумя объектами Xcode с Swift

Как я могу различать две цели Xcode с помощью Swift? Идея состоит в том, чтобы сделать бесплатную и платную версию приложения с той же базой кода в Xcode.

С объективом C я могу использовать макросы препроцессора, но с Swift они недоступны.

Ответ 1

Начиная с Xcode 8, вы можете установить условия компиляции в настройках сборки для каждой цели в разделе Условия активной компиляции.

Active Compilation Conditions Screenshot

С этим набором вы можете использовать:

#if FREE
   //do something
#endif

Подробнее см. i40west answer и комментарии.

Ответ 2

В Xcode перейдите в конфигурацию сборки для цели. Найдите раздел под названием Swift Compiler - пользовательские флаги, который содержит параметр Другие быстрые флаги.

Добавьте флаг командной строки для компилятора, чтобы добавить флаг, почти так же, как youd делать с компилятором C.

Swift Compiler Flags

Теперь вы получили -D Something, который передается компилятору Swift. В коде Swift теперь можно сделать следующее:

#if Something
    let foo = "bar"
#endif

Он очень похож на препроцессор C, но в отличие от C весь код во всех условных разделах должен быть синтаксически правильным или программа не будет компилироваться. Таким образом, вы можете установить флаг для каждой цели в настройках сборки и использовать их в своем коде.

Ответ 3

Один из способов - добавить флаги к цели и использовать препроцессор. Но другой способ, я думаю, будет использовать что-то вроде этого

if Bundle.appTarget == "" { } else { }


extension Bundle {

    public static var appVersion: String? {
        return Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String
    }

    public static var appBuild: String? {
        return Bundle.main.object(forInfoDictionaryKey: kCFBundleVersionKey as String) as? String
    }

    public static func _version() -> String {
        let dictionary = Bundle.main.infoDictionary!
        let version = dictionary["CFBundleShortVersionString"] as! String
        let build = dictionary["CFBundleVersion"] as! String
        return "\(version) build \(build)"
    }

    public static var appTarget: String? {
        if let targetName = Bundle.main.object(forInfoDictionaryKey: "CFBundleExecutable") as? String {
            return targetName
        }
        return nil
    }
}