iOS 11中的NSFoundationVersionNumber - 如何以编程方式检测iOS版本

18

在之前的iOS版本中,我使用NSFoundationVersionNumber来检测iOS版本:

#define IS_IOS10orHIGHER (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_9_x_Max)
#define IS_IOS9orHIGHER (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_8_3)
#define IS_IOS8orHIGHER (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1)
#define IS_IOS7orHIGHER (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1)
#define IS_IOS6orHIGHER (floor(NSFoundationVersionNumber) >= NSFoundationVersionNumber_iOS_6_0)
...

现在我想为iOS 11做同样的事情,但我找不到正确的NSFoundationVersionNumber文档显示NSFoundationVersionNumber_iOS_9_x_Max是最新的。

那么,如何检测使用的是iOS 11的正确NSFoundationVersionNumber

3个回答

84

如果您使用的是 Xcode 9 或更高版本,您可以使用 @available 属性:

if (@available(iOS 11.0, *)) {
    NSLog(@"newest");
} else {
    NSLog(@"not newest");
}
在Swift中,使用的是#available而不是@available。这种方法更好的原因是编译器会在必要时抑制相关警告。因此,在上面的示例中,您可以在if块中使用在iOS 11.0中引入的API,而不会收到关于这些API在项目部署目标上不可用的警告。

1
我喜欢这种新的方法 :) - Genki
根据我上面的评论,由于使用浮点数进行比较,所以被接受的答案可能存在舍入误差 - 这总是一个微妙错误的来源。在我看来,这是更好的方法。 - Jim Leask
1
要明确的是,我认为@CharlesSrstka的答案是正确的,并且应该被接受,而不是使用systemVersion的浮点比较的那个答案,因为那样可能会导致微妙的错误。 - Jim Leask
1
@onmyway133,你的if语句中只有@available这个条件吗?还是你通过&&||与其他条件组合在一起了?后者会导致警告。不幸的是,可用性检查必须单独进行。 - Charles Srstka
1
@KevinAmiranoff iOS 11(或您检查的任何版本)及以上。如果您需要特别检查某个特定的操作系统版本,则最好使用NSProcessInfooperatingSystemVersion属性:https://developer.apple.com/documentation/foundation/nsprocessinfo/1410906-operatingsystemversion?language=objc - Charles Srstka
显示剩余3条评论

15

1
实际上,由于浮点运算可能会出现故障。在我的系统上,[[UIDevice currentDevice] systemVersion] floatValue]11.1999998。这是标准的浮点舍入问题,所以如果我要寻找 11.2,这将失败。 - Jim Leask

2

Apple NSProcessInfo

现在,苹果在NSProcessInfo中提供了NSOperatingSystemVersion结构体。

您可以将其与isOperatingSystemAtLeastVersion:一起使用,或者只需检查3个字段即可准确知道运行您的应用程序的系统版本。

它适用于obj c和swift两种编程语言。


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