xcode Swift 相当于 Objective-C 的“#ifdef __IPHONE_11_0”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44424337/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 10:01:11  来源:igfitidea点击:

What's the Swift equivalent of Objective-C's "#ifdef __IPHONE_11_0"?

swiftxcodemacrosversioning

提问by Matthias Bauch

I want to use Xcode 9 to add iOS 11 code to my project while keeping the option to compile the project with Xcode 8 which only supports iOS 10.

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

In Objective-C I can do this by using a preprocessor directive to check if __IPHONE_11_0is defined. Which will hide the code if I'm compiling with a Base SDK earlier than iOS 11. Like this:

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

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

Is there a way to do that in Swift?

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

if #available(iOS 11.0, *)doesn't work because that's a runtime check.

if #available(iOS 11.0, *)不起作用,因为这是运行时检查。

采纳答案by Lily Ballard

The iOS 11 SDK comes with Swift 3.2 (or Swift 4), so you can use a Swift version check to accomplish the same thing:

iOS 11 SDK 随附 Swift 3.2(或 Swift 4),因此您可以使用 Swift 版本检查来完成相同的操作:

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

回答by pesch

This is the solution suggested by Apple:

这是Apple建议的解决方案:

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

Please refer to this resource(watch video on mark 6:50 for more details)

请参阅此资源(观看标记 6:50 的视频了解更多详情)

回答by Carly

If you want to put the condition outside of the function, you could do it like below.

如果你想把条件放在函数之外,你可以像下面那样做。

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

回答by Prabhat Pandey

You can achieve, by doing this for function like below

您可以通过对如下功能执行此操作来实现

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

Or if you want check inside function write this

或者如果你想检查内部函数写这个

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
}

回答by DavidPhillipOster

I understand. I've got an old Mac I like to use that is too old for Xcode 9, so I want to also be able to sometimes compile my projects under Xcode 8.

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

But if all you want is to support both iOS 10 and iOS 11, the easy way is to just set the minimum SDK of the Xcode target to 10.0, and always compile with the iOS 11 SDK. Swift will work for you in that case, and give you syntax errors unless you correctly use if #available(iOS 11.0, *) {

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

You'll still be able to test under both iOS 10 and iOS 11 and you won't need to bother with Xcode 8.

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

From the point of view of Xcode 8, you are trying to compile source code from the future. There's no good solution for Xcode 8.

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

Going forward, here is the solution:

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

In Xcode 9.3 (Swift 4.1), you can say:

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

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

and your code will still compile under Xcode 9.3, but skipping that future stuff that needs a hypothetical Xcode 10.0 or later.

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

#if canImport(moduleName)was only added in Swift 4.1, which Xcode 8 can't handle. But even this only works for entire modules that Apple adds in the future. If Apple merely extends an existing class with new methods, as in your navigationController.navigationBar.prefersLargeTitlesyou still won't be able to test for prefersLargeTitlesdirectly, but you can find another framework that Apple introduced at the same time as prefersLargeTitlesand check for the existence of that framework with #if canImport(…).

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