使用 Swift 区分两个 Xcode 目标

Posted

技术标签:

【中文标题】使用 Swift 区分两个 Xcode 目标【英文标题】:Differentiate between two Xcode targets with Swift 【发布时间】:2014-12-03 23:48:31 【问题描述】:

如何?我们的想法是在 Xcode 中制作具有相同代码库的应用程序的免费和付费版本。

对于 Objective C,我可以使用预处理器宏,但对于 Swift,这些是不可用的。

【问题讨论】:

【参考方案1】:

在 Xcode 中,进入目标的构建配置。找到名为 Swift Compiler - Custom Flags 的部分,其中包含名为 Other Swift Flags 的设置。

为编译器添加一个命令行标志来添加一个标志,就像你对 C 编译器所做的那样。

现在您已将 -D Something 传递给 Swift 编译器。在您的 Swift 代码中,您现在可以这样做:

#if Something
    let foo = "bar"
#endif

它看起来很像 C 预处理器,但与 C 不同的是,所有条件部分中的所有代码都必须在语法上正确,否则程序将无法编译。因此,您可以在构建设置中为每个目标设置一个标志,并在您的代码中使用它们。

【讨论】:

更重要的是,#if 中的所有代码,无论是否激活,都必须是一个完整的句法单元。所以你不能说,只在 func 声明周围放置一个 #if/#else/#endif 并将函数体留在 #if 之外。 这是故事板中的作品吗,我想根据故事板中的目标更改图像 我不明白。不应该是if Something == QA else if Something == Stage`... 你写它的方式,似乎那个标志的存在就是所有必要的。如果两个构建具有相同的标志会发生什么?! 如果您需要测试多个值,那么可以。这只是一个直接的布尔值。 如果我需要在一个目标中而不是在其他目标中包含资源 [swift 文件或 nib],这是否可行。【参考方案2】:

从 Xcode 8 开始,您可以在 Active Compilation Conditions 下的 Build Settings 中为每个目标设置编译条件。

有了这些你可以使用:

#if FREE
   //do something
#endif

更多详情请参阅i40west answer 和 cmets。

【讨论】:

【参考方案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
    

【讨论】:

你也可以使用 Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") 这个键应该在 Info.plist 中定义

以上是关于使用 Swift 区分两个 Xcode 目标的主要内容,如果未能解决你的问题,请参考以下文章

Xcode Swift 在“应用程序目标”与“框架目标”中导入代码——有啥区别?

UIScreen.mainScreen().nativeBounds.height 无法使用 Xcode 7/Swift 2,目标 iOS7

目标 C 项目中的 Xcode 8.3 Swift 版本错误 (SWIFT_VERSION)

将多个声音(目标 c)播放到 Swift(xcode 7)的代码帮助

Xcode 8.2使用旧版Swift问题[重复]

Xcode 7 支持 watch OS1 和 OS2