基于Xcode版本的条件编译

时间:2016-05-10 14:27:13

标签: xcode swift

我为Xcode构建了一个主要通过Alcatraz部署的插件。该实用程序从GitHub获取插件的源代码,编译它,如果成功,则将其安装在正确的目录中。它一直运行得很好,直到Xcode的7.3版本与Swift 2.2一起发布。

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用户手动下载和安装的副本。

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

由于Swift支持条件编译,您可以设置自己的条件。

在必须使用旧版Swift的项目中使用类似#if SWIFT_2_0的内容并定义-D SWIFT_2_0

答案 1 :(得分:0)

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

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

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

然后在代码中,应该可以执行以下操作:

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