什么是Swift相当于Objective-C" #ifdef __IPHONE_11_0"?

时间:2017-06-07 23:29:55

标签: swift xcode macros versioning

我想使用Xcode 9将iOS 11代码添加到我的项目中,同时保留使用仅支持iOS 10的Xcode 8编译项目的选项。

在Objective-C中我可以通过使用预处理器指令来检查是否定义了__IPHONE_11_0。如果我使用早于iOS 11的Base SDK进行编译,这将隐藏代码。像这样:

#ifdef __IPHONE_11_0
    if (@available(iOS 11.0, *)) {
        self.navigationController.navigationBar.prefersLargeTitles = YES;
    }
#endif

有没有办法在Swift中做到这一点?

if #available(iOS 11.0, *)无法正常工作,因为这是运行时检查。

5 个答案:

答案 0 :(得分:15)

iOS 11 SDK附带Swift 3.2(或Swift 4),因此您可以使用Swift版本检查来完成同样的事情:

#if swift(>=3.2)
    if #available(iOS 11.0, *) {
        …
    }
#endif

答案 1 :(得分:4)

这是Apple建议的解决方案:

if #available(iOS 11.0, *) {
    // iOS 11 specific stuff here
} else {
    // non iOS 11 stuff here
}

请参阅this resources(有关详情,请观看标记6:50的视频)

答案 2 :(得分:1)

如果要将条件放在函数之外,则可以按以下方式进行操作。

@available(iOS 11.0, *)
func functionName() {
 // function contents
}

答案 3 :(得分:1)

您可以通过对以下功能执行此操作

@available(iOS 11.0, *)
func myFunction() {
 // function defination 
}

或者如果您想检查函数内部内容,请写

if #available(iOS 11.0, *) {
    // iOS 11 specific stuff here
} else if #available(iOS 10.0, *) {
   // iOS 10 specific stuff here
} else {
    // non iOS 11 & 10 stuff here
}

答案 4 :(得分:0)

我明白。我有一个旧的Mac,我喜欢使用它对于Xcode 9而言太旧了,所以我希望有时能够在Xcode 8下编译我的项目。

但如果您只想支持iOS 10和iOS 11,那么简单的方法就是将Xcode目标的最小SDK设置为10.0,并始终使用iOS 11 SDK进行编译。在这种情况下,Swift会为你工作,除非你正确使用如果#available(iOS 11.0,*){

,否则会给你语法错误

你仍然可以在iOS 10和iOS 11下进行测试,你不需要为Xcode 8而烦恼。

从Xcode 8的角度来看,您正在尝试从未来编译源代码。 Xcode 8没有很好的解决方案。

展望未来,这是解决方案:

在Xcode 9.3(Swift 4.1)中,您可以说:

#if canImport(MagiciOS12Kit)
  if #available(iOS 12.0, *) {
     MagiciOS12Class.standard.method()
  }
#endif

并且您的代码仍将在Xcode 9.3下编译,但跳过未来需要假设的Xcode 10.0或更高版本的东西。

#if canImport(moduleName)仅在Swift 4.1中添加,Xcode 8无法处理。但即使这只适用于Apple未来添加的整个模块。如果Apple仅使用新方法扩展现有类,如 navigationController.navigationBar.prefersLargeTitles ,您仍然无法直接测试 prefersLargeTitles ,但您可以找到Apple推出的另一个框架 prefersLargeTitles ,并使用 #if canImport(...)检查该框架是否存在。