如何在同一源文件中有条件地编译特定于版本的Swift(1.2 vs 2.0)代码?

Lea*_*s2D 5 xcode preprocessor compilation swift swift2

我有一个与我的框架捆绑在一起的Swift演示项目.我想确保演示中的Swift代码与Xcode 6(Swift 1.2)和Xcode 7(Swift 2.0)成功编译,无需用户干预.

由于Swift中只有边缘预处理器支持,如何在编译时确定使用哪个版本的Swift或Xcode来编译代码?

现在,这是重要的细节:

  • 它必须自动工作!
    • 在Xcode 6中打开项目 - >编译Swift 1.2代码.
    • 在Xcode 7中打开项目 - >编译Swift 2.0代码.

没有构建设置或其他需要用户以某种方式指定她正在使用的Swift/Xcode版本的方法.

我一直在想:这是一项微不足道的任务,用Swift怎么可能不可能?

作为一个框架开发人员,这让我感到疯狂,因为Swift项目的成功编译现在完全取决于用户的Xcode版本,我不能要求他们全部"更新到Xcode 6.4",稍后不得不问他们一遍又一遍地"更新到Xcode 7.1".疯了吧!

另一种选择当然是拥有单独的演示项目,管理不同的代码库,每个版本的Swift都有一个.并希望用户知道哪个项目适用于她的Xcode版本.不是一个真正的选择.

遗憾的是,另一种替代方案,即根本不使用任何Swift 2.0的增强功能.有一些语法,类和方法在一个或另一个Swift版本中不起作用,只是因为编译器在较新的Xcode版本中更加挑剔.

Dan*_*bar 5

您可以使用Xcode的一些高级构建设置来完成此操作,尤其是:

  • XCODE_VERSION_MAJOR:将Xcode主版本编码为字符串,例如“ 0700”。
  • EXCLUDED_SOURCE_FILE_NAMES:源文件的“ fnmatch”风格样式,默认情况下不包括在内。
  • INCLUDED_SOURCE_FILE_NAMES:要包含的源文件的“ fnmatch”样式样式。

我一般不建议这样做,因为这会使大多数Xcode用户难以理解您的项目,但是如果您绝对想使它工作,则可以使用此技术。

完成的方式如下:

  1. 对于需要版本控制的任何源文件,将其命名为“ Thing-Versioned-0600.swift”和“ Thing-Versioned-0700.swift”。确保两个文件都在源构建阶段。

  2. 通过添加项目级别的构建设置,使用排除的机制来防止默认情况下编译任何版本控制的文件。EXCLUDED_SOURCE_FILE_NAMES = *-Versioned-*.swift

  3. 使用包含的机制,通过添加另一个项目级别的构建设置,仅添加回与当前Xcode主版本匹配的文件INCLUDED_SOURCE_FILE_NAMES = *-Versioned-$(XCODE_VERSION_MAJOR).swift


Edw*_*eer 0

在项目中拥有 2 个版本的代码将不起作用,因为代码无法编译。没有用于基于版本的条件编译的编译器指令。

有一种可行的解决方法(未测试)

首先创建 3 个文件,分别命名为 version_current.swift、version_1_2.swift 和 version_2.swift。确保只有 version_current.swift 是您的构建目标的一部分。

然后创建一个新的构建脚本阶段并将其放置在“编译源”阶段的正上方。在该脚本中,您将复制 1_2 或 2 版本的内容来覆盖当前版本。

我的脚本知识不太好,所以我无法为您提供太多帮助。您可以使用如下代码获取版本:

$ xcrun swift -version
Run Code Online (Sandbox Code Playgroud)

然后只执行一条复制语句。

但这仅适用于系统上的默认 Xcode 版本。当您想使用不同的版本时,您还必须更改默认版本。