我想使用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, *)
无法正常工作,因为这是运行时检查。
答案 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(...)检查该框架是否存在。