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

时间:2015-08-06 17:24:21

标签: xcode swift compilation preprocessor swift2

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

由于有only marginal preprocessor support in 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版本中更加挑剔。

2 个答案:

答案 0 :(得分:4)

您可以使用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

答案 1 :(得分:0)

项目中包含2个版本的代码,因为代码无法编译,所以无法正常工作。没有基于版本的条件编译的编译器指令。

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

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

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

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

$ xcrun swift -version

然后只执行复制声明。

但是这只适用于您系统上的默认Xcode版本。如果要使用其他版本,还必须更改默认版本。