基于Xcode版本的条件编译

3
我已经为Xcode构建了一个插件,主要通过Alcatraz部署。该实用程序从GitHub获取我的插件源代码,编译它,并在成功后将其安装到正确的目录中。这一直运行得很好,直到发布Swift 2.2的Xcode 7.3版本。
Swift 2.2引入了一种新的指定选择器的方式。以前,您需要提供一个带有函数名称的字符串,例如:
NSNotificationCenter.defaultCenter().addObserver( self, selector: "applicationFinishedLoading:", name: NSApplicationDidFinishLaunchingNotification, object: nil )

然而,新的方法使用 #selector,如下所示:
NSNotificationCenter.defaultCenter().addObserver( self, selector: #selector(ColorSenseRainbow.applicationFinishedLoading(_:)), name: NSApplicationDidFinishLaunchingNotification, object: nil )

如果我将我的代码转换成新方法,那么使用旧版本Xcode(7.2.1及更早版本)的用户将无法使用我的插件,因为它不知道新的#selector。我知道这一点是因为我已经进行了转换,以消除过期警告,并得到了用户反馈。但很可能下一个Xcode版本将转移到Swift 3,我将不得不做出这个改变。

因此,我更喜欢找到一种方式让编译器选择适用于Xcode版本的代码。类似于这样的伪代码。

#if (XCode_Version >= 7.3)
    // use @selector ( ThisClass.functionName)
#else
    // use selector: "functionName:"
#endif

我知道有一个swift()函数可以用来告诉版本,但那只在Swift 2.2中引入,如果我使用它,编译将失败,无法在Xcode 7.2.1及以下版本中使用。这让我陷入与@selector函数相同的境地。

另一种选择是将我即将发布的版本作为最后一个使用"functionName:"方法的版本。然后我会在GitHub上提供一个预编译的副本供旧版本Xcode的用户手动下载和安装。

感谢您的帮助。


维护正在开发中的语言的旧版支持似乎不明智。这样做几乎没有什么好处,没有理由不使用最新的Xcode/Swift版本。 - Alexander
我正在使用最新的Xcode/Swift,但插件代码是由全球数百人下载和编译的。我无法决定他们的开发环境选择,因此如果可能的话,我希望能够支持他们。他们可能有不升级不到一年的应用程序的充分理由。我说的是支持Xcode 7.2.1而不是版本4。 - CanadianMacFan
Swift作为一门语言本身正在快速发展。没有什么是确定的,许多事情都在迅速变化,甚至包括像Array字面量语法这样基本的东西。任何想要编写Swift代码的人都应该理解源代码和ABI的不稳定性将在未来一段时间内存在很大程度上。支持一些毫无意义的东西。 - Alexander
2个回答

3

我最近遇到了这个问题,以下是我解决它的方法。

Xcode导出环境变量XCODE_VERSION_ACTUAL,它以0910的格式表示Xcode的当前版本,例如在Xcode 9.1中。可以利用这个变量创建一个编译标志来进行条件编译。

在项目设置中,创建一个构建设置,例如XCODE_0910_COMPILATION_FLAGS,并将其设置为-DXCODE_VERSION_9_1。然后,在其他Swift标志中添加$(XCODE_$(XCODE_VERSION_ACTUAL)_COMPILATION_FLAGS),这将有条件地引入编译标志。

然后在代码中,应该可以做到像这样:

#if XCODE_VERSION_9_1
  // do something conditional to Xcode 9.1
#endif

0
由于Swift支持条件编译,您可以设置自己的条件。
在必须使用旧版本Swift的项目中,可以使用类似于#if SWIFT_2_0-D SWIFT_2_0的方式进行定义。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接