首页 > 代码库 > iOS版本

iOS版本

1.静态检查

静态检查,即在编译时段就检查当前SDK编译与构建应用是否能使用某个API或已经不支持某个API。

编译常量

__IPHONE_OS_VERSION_MIN_REQUIRED

用来判断是否当前SDK版本“仍然”支持或具有某些功能。

#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000
    //minimum deployment target is 8.0, so it’s safe to use iOS 8-only code
    当前SDK最小支持的设备系统,即8.0,所以在iOS 8.0设备上是安全的

#else
    //you can use iOS8 APIs, but the code will need to be backwards
    //compatible or it will crash when run on an iOS 7 device
    你仍然可以使用iOS 8的API,但是在iOS 7的设备上可能会crash.
#endif

__IPHONE_OS_VERSION_MAX_ALLOWED

用来判断是否当前版本“开始”支持或具有某些功能;

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000
    //you can use iOS 10 APIs here because the SDK supports them
    //but the code may still crash if run on an iOS 8 device
    可以使用最新的iOS 10的API,开始支持的新功能。但是仍然可能会在iOS 8的设备上crash。
#else
    //this code can’t use iOS 10 APIs as the SDK version doesn’t support them
    不能使用iOS 10的API,只能使用iOS 10之前的。
#endif

针对Xcode的旧版本,或者设备上的就版本,不存在相应的宏,采用如下定义:

#ifndef __IPHONE_10_0
#define __IPHONE_10_0 100000
#endif
 
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
 
#else
 
#endif

2.动态检查

CoreFoudation/NSFoundation版本宏

类似于iOS 系统版本宏,系统还给出了CoreFoudation和NSFoudation宏,并且给出了kCFCoreFoundationVersionNumber和NSFoundationVersionNumber两个值。这两个值均是double值。

在iOS10.2.1系统上,以上两个值,分别是:1348.220000、1349.130000。
在Debug下,两个值的存储po出来分别是:1348.22、1349.1300000000001。

kCFCoreFoundationVersionNumber

详见 CoreFoundatin/CFBase.h中定义。

NSFoundationVersionNumber

详见 Foundation/NSObjRuntime.h中定义。

针对上面的宏,写起来复杂,所以可以定义一个宏,来简化书写:

#ifndef kCFCoreFoundationVersionNumber_iPhoneOS_10_0
#define kCFCoreFoundationVersionNumber_iPhoneOS_10_0 1299
#endif

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000
#define IF_IOS10_OR_GREATER(...) if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iPhoneOS_10_0) { __VA_ARGS__ }
#else
#define IF_IOS10_OR_GREATER(...)
#endif

#define IF_PRE_IOS10(...) if (kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iPhoneOS_10_0) { __VA_ARGS__ }

IF_IOS10_OR_GREATERIF_PRE_IOS10就可以在使用中快捷调用。

IF_IOS10_OR_GREATER
(
    //iOS 10 code here
);

然而,即使上面这种方法可以简单的检查系统版本,你仍然无法保证绝对正确,因为你会发现以上宏中不同的系统版本中存在相同的值。

缺陷:当你要判断那些刚好存在相同值的版本的时候,也是一个危险的判断。

 

3.检查运行的iOS 系统版本

if ([[ [UIDevice currentDevice] systemVersion] floatValue] >= 10.0) {
}

 

注意:上面的判断方法,在判断整数版本的时候,使用起来挺方便,也不会出什么大问题。但是仍然是极其危险的。因为float在计算机中的存储,是近似而非精确。

比如,最新的iOS 10.2.1系统,有以下一段代码:

NSString *version = [[UIDevice currentDevice] systemVersion];
int int_ver = [version intValue];
float float_ver = [version floatValue];
NSLog(@"%@-%d-%f",version,int_ver,float_ver);

 


打印出来如下的结果:

10.2.1-10-10.200000

 

可以看出,10.2.1打印出来的floatValue值,是【10.20000】,这还算小事。更为致命的是,在控制台调试时发现:

技术分享

所以,假如比较10.2.1和10.2.2比较,就很难得出结果。

鉴于此,以上方法不推荐使用!最好不用!

那么,什么是好的运行时判断系统的方法呢?

定义判断版本的宏:

#define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)

 

 
 

但是,由于NSString的compare方法本身的缺陷:

NSInteger compareResult = [@"10.0" compare:@"10" options:NSNumericSearch];

 


遗憾的是,上面的系统版本判断也是有漏洞的。但是相对于之前的漏洞,这个漏洞似乎可以接受。
上面返回的结果:NSOrderedDescending,即10.0相比于10是低版本。

4.iOS 8之后,NSOperatingSystemVersion

NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion];

 

NSProcessInfo还提供了:

NSOperatingSystemVersion v = (NSOperatingSystemVersion){8,1,3};
if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:v]) {
 
}

 

以上这个方法,只有在iOS 8之后,但是对于一些超级APP,仍然在支持iOS 7,所以也就无能为力了。

 转自

iOS版本