我想检查设备的iOS
版本是否大于3.1.3
我尝试过这样的事情:
[[UIDevice currentDevice].systemVersion floatValue]
但它不起作用,我只想要一个:
if (version > 3.1.3) { }
我怎样才能做到这一点?
答案 0 :(得分:1046)
/*
* System Versioning Preprocessor Macros
*/
#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)
/*
* Usage
*/
if (SYSTEM_VERSION_LESS_THAN(@"4.0")) {
...
}
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"3.1.1")) {
...
}
答案 1 :(得分:951)
从Swift 2.0开始,您可以在#available
或if
中使用guard
来保护仅在某些系统上运行的代码。
if #available(iOS 9, *) {}
在Objective-C中,您需要检查系统版本并执行比较。
[[NSProcessInfo processInfo] operatingSystemVersion]
。
从Xcode 9开始:
if (@available(iOS 9, *)) {}
在Objective-C和Swift中,在极少数情况下,最好避免依赖操作系统版本作为设备或操作系统功能的指示。通常有一种更可靠的方法来检查特定要素或类是否可用。
检查是否存在API:
例如,您可以使用UIPopoverController
检查当前设备上是否有NSClassFromString
:
if (NSClassFromString(@"UIPopoverController")) {
// Do something
}
对于弱链接类,直接向类发送消息是安全的。值得注意的是,这适用于未明确链接为“必需”的框架。对于缺少的类,表达式的计算结果为nil,不符合条件:
if ([LAContext class]) {
// Do something
}
某些类(如CLLocationManager
和UIDevice
)提供了检查设备功能的方法:
if ([CLLocationManager headingAvailable]) {
// Do something
}
检查是否存在符号:
偶尔,您必须检查是否存在常量。这在iOS 8中引入了UIApplicationOpenSettingsURLString
,用于通过-openURL:
加载设置应用。在iOS 8之前该值不存在。将nil传递给此API将崩溃,因此您必须首先检查是否存在常量:
if (&UIApplicationOpenSettingsURLString != NULL) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
}
与操作系统版本进行比较:
让我们假设您面临检查操作系统版本的相对罕见的需求。对于面向iOS 8及更高版本的项目,NSProcessInfo
包含一种执行版本比较的方法,错误机会较少:
- (BOOL)isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion)version
定位较旧系统的项目可以在systemVersion
上使用UIDevice
。 Apple在他们的GLSprite示例代码中使用它。
// A system version of 3.1 or greater is required to use CADisplayLink. The NSTimer
// class is used as fallback when it isn't available.
NSString *reqSysVer = @"3.1";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending) {
displayLinkSupported = TRUE;
}
如果由于某种原因您决定systemVersion
是您想要的,请确保将其视为字符串,否则您可能会截断修补程序修订号(例如3.1.2 - > 3.1)。
答案 2 :(得分:249)
根据official Apple docs的建议:您可以使用NSObjCRuntime.h
标头文件中的NSFoundationVersionNumber
。
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
// here you go with iOS 7
}
答案 3 :(得分:82)
在 Objective-C :
中启动Xcode 9if (@available(iOS 11, *)) {
// iOS 11 (or newer) ObjC code
} else {
// iOS 10 or older code
}
在 Swift :
中启动Xcode 7if #available(iOS 11, *) {
// iOS 11 (or newer) Swift code
} else {
// iOS 10 or older code
}
对于版本,您可以指定MAJOR,MINOR或PATCH(有关定义,请参阅http://semver.org/)。例子:
iOS 11
和iOS 11.0
是相同的最小版本iOS 10
,iOS 10.3
,iOS 10.3.1
是不同的最低版本您可以输入任何这些系统的值:
iOS
,macOS
,watchOS
,tvOS
取自one of my pods的真实案例:
if #available(iOS 10.0, tvOS 10.0, *) {
// iOS 10+ and tvOS 10+ Swift code
} else {
// iOS 9 and tvOS 9 older code
}
答案 4 :(得分:36)
这用于在Xcode中检查兼容的SDK版本,如果你有一个拥有不同Xcode版本的大型团队或支持共享相同代码的不同SDK的多个项目:
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
//programming in iOS 8+ SDK here
#else
//programming in lower than iOS 8 here
#endif
您真正想要的是检查设备上的iOS版本。你可以这样做:
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) {
//older than iOS 8 code here
} else {
//iOS 8 specific code here
}
Swift版本:
if let version = Float(UIDevice.current.systemVersion), version < 9.3 {
//add lower than 9.3 code here
} else {
//add 9.3 and above code here
}
当前版本的swift应该使用此功能:
if #available(iOS 12, *) {
//iOS 12 specific code here
} else {
//older than iOS 12 code here
}
答案 5 :(得分:36)
尝试:
NSComparisonResult order = [[UIDevice currentDevice].systemVersion compare: @"3.1.3" options: NSNumericSearch];
if (order == NSOrderedSame || order == NSOrderedDescending) {
// OS version >= 3.1.3
} else {
// OS version < 3.1.3
}
答案 6 :(得分:34)
在Swift 2.0中,Apple使用更方便的语法添加了可用性检查(阅读更多here)。现在,您可以使用更清晰的语法检查操作系统版本:
if #available(iOS 9, *) {
// Then we are on iOS 9
} else {
// iOS 8 or earlier
}
这是首选检查respondsToSelector
等(What's New In Swift)。现在,如果您没有正确地保护代码,编译器将始终发出警告。
iOS 8中的新功能NSProcessInfo
允许更好的语义版本检查。
对于 iOS 8.0 或更高版本的最低部署目标,请使用
NSProcessInfo
operatingSystemVersion
或isOperatingSystemAtLeastVersion
。
这将产生以下结果:
let minimumVersion = NSOperatingSystemVersion(majorVersion: 8, minorVersion: 1, patchVersion: 2)
if NSProcessInfo().isOperatingSystemAtLeastVersion(minimumVersion) {
//current version is >= (8.1.2)
} else {
//current version is < (8.1.2)
}
对于 iOS 7.1 或更低版本的最低部署目标,请使用compare with
NSStringCompareOptions.NumericSearch
上的UIDevice systemVersion
。
这会产生:
let minimumVersionString = "3.1.3"
let versionComparison = UIDevice.currentDevice().systemVersion.compare(minimumVersionString, options: .NumericSearch)
switch versionComparison {
case .OrderedSame, .OrderedDescending:
//current version is >= (3.1.3)
break
case .OrderedAscending:
//current version is < (3.1.3)
fallthrough
default:
break;
}
更多阅读NSHipster。
答案 7 :(得分:8)
我总是将它们保存在我的Constants.h文件中:
#define IS_IPHONE5 (([[UIScreen mainScreen] bounds].size.height-568)?NO:YES)
#define IS_OS_5_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 5.0)
#define IS_OS_6_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0)
#define IS_OS_7_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
答案 8 :(得分:6)
使用nv-ios-version项目(Apache许可证,版本2.0)中包含的版本类,可以轻松获取和比较iOS版本。下面的示例代码转储iOS版本并检查版本是否大于或等于6.0。
// Get the system version of iOS at runtime.
NSString *versionString = [[UIDevice currentDevice] systemVersion];
// Convert the version string to a Version instance.
Version *version = [Version versionWithString:versionString];
// Dump the major, minor and micro version numbers.
NSLog(@"version = [%d, %d, %d]",
version.major, version.minor, version.micro);
// Check whether the version is greater than or equal to 6.0.
if ([version isGreaterThanOrEqualToMajor:6 minor:0])
{
// The iOS version is greater than or equal to 6.0.
}
// Another way to check whether iOS version is
// greater than or equal to 6.0.
if (6 <= version.major)
{
// The iOS version is greater than or equal to 6.0.
}
项目页面:nv-ios-version
TakahikoKawasaki/nv-ios-version
Blog:在运行时获取并比较iOS版本与版本类
Get and compare iOS version at runtime with Version class
答案 9 :(得分:6)
+(BOOL)doesSystemVersionMeetRequirement:(NSString *)minRequirement{
// eg NSString *reqSysVer = @"4.0";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
if ([currSysVer compare:minRequirement options:NSNumericSearch] != NSOrderedAscending)
{
return YES;
}else{
return NO;
}
}
答案 10 :(得分:5)
<强>的UIDevice + IOSVersion.h 强>
@interface UIDevice (IOSVersion)
+ (BOOL)isCurrentIOSVersionEqualToVersion:(NSString *)iOSVersion;
+ (BOOL)isCurrentIOSVersionGreaterThanVersion:(NSString *)iOSVersion;
+ (BOOL)isCurrentIOSVersionGreaterThanOrEqualToVersion:(NSString *)iOSVersion;
+ (BOOL)isCurrentIOSVersionLessThanVersion:(NSString *)iOSVersion;
+ (BOOL)isCurrentIOSVersionLessThanOrEqualToVersion:(NSString *)iOSVersion
@end
<强>的UIDevice + IOSVersion.m 强>
#import "UIDevice+IOSVersion.h"
@implementation UIDevice (IOSVersion)
+ (BOOL)isCurrentIOSVersionEqualToVersion:(NSString *)iOSVersion
{
return [[[UIDevice currentDevice] systemVersion] compare:iOSVersion options:NSNumericSearch] == NSOrderedSame;
}
+ (BOOL)isCurrentIOSVersionGreaterThanVersion:(NSString *)iOSVersion
{
return [[[UIDevice currentDevice] systemVersion] compare:iOSVersion options:NSNumericSearch] == NSOrderedDescending;
}
+ (BOOL)isCurrentIOSVersionGreaterThanOrEqualToVersion:(NSString *)iOSVersion
{
return [[[UIDevice currentDevice] systemVersion] compare:iOSVersion options:NSNumericSearch] != NSOrderedAscending;
}
+ (BOOL)isCurrentIOSVersionLessThanVersion:(NSString *)iOSVersion
{
return [[[UIDevice currentDevice] systemVersion] compare:iOSVersion options:NSNumericSearch] == NSOrderedAscending;
}
+ (BOOL)isCurrentIOSVersionLessThanOrEqualToVersion:(NSString *)iOSVersion
{
return [[[UIDevice currentDevice] systemVersion] compare:iOSVersion options:NSNumericSearch] != NSOrderedDescending;
}
@end
答案 11 :(得分:5)
使用swift Forget [[UIDevice currentDevice] systemVersion]和NSFoundationVersionNumber检查系统版本的新方法。
我们可以使用NSProcessInfo -isOperatingSystemAtLeastVersion
import Foundation
let yosemite = NSOperatingSystemVersion(majorVersion: 10, minorVersion: 10, patchVersion: 0)
NSProcessInfo().isOperatingSystemAtLeastVersion(yosemite) // false
答案 12 :(得分:4)
派对有点晚了,但鉴于iOS 8.0,这可能是相关的:
如果可以避免使用
[[UIDevice currentDevice] systemVersion]
而是检查是否存在方法/类/其他任何内容。
if ([self.yourClassInstance respondsToSelector:@selector(<yourMethod>)])
{
//do stuff
}
我发现它对于位置管理器非常有用,我必须为iOS 8.0调用requestWhenInUseAuthorization,但该方法不适用于iOS&lt; 8
答案 13 :(得分:4)
一般来说,最好询问对象是否可以执行给定的选择器,而不是检查版本号以确定它是否必须存在。
如果这不是一个选项,那么你需要在这里做一点小心,因为[@"5.0" compare:@"5" options:NSNumericSearch]
会返回NSOrderedDescending
,而这可能完全没有意图;我可能期望NSOrderedSame
在这里。这至少是一个理论上的问题,在我看来值得防范。
另外值得考虑的是可能无法合理地比较不良版本输入。 Apple提供了三个预定义的常量NSOrderedAscending
,NSOrderedSame
和NSOrderedDescending
但我可以想到一些名为NSOrderedUnordered
的东西用于我无法比较两件事情和我想返回一个表示这个的值。
更重要的是,Apple有一天会扩展他们的三个预定义常量以允许各种返回值,这使得比较!= NSOrderedAscending
不明智。
说到这里,请考虑以下代码。
typedef enum {kSKOrderedNotOrdered = -2, kSKOrderedAscending = -1, kSKOrderedSame = 0, kSKOrderedDescending = 1} SKComparisonResult;
@interface SKComparator : NSObject
+ (SKComparisonResult)comparePointSeparatedVersionNumber:(NSString *)vOne withPointSeparatedVersionNumber:(NSString *)vTwo;
@end
@implementation SKComparator
+ (SKComparisonResult)comparePointSeparatedVersionNumber:(NSString *)vOne withPointSeparatedVersionNumber:(NSString *)vTwo {
if (!vOne || !vTwo || [vOne length] < 1 || [vTwo length] < 1 || [vOne rangeOfString:@".."].location != NSNotFound ||
[vTwo rangeOfString:@".."].location != NSNotFound) {
return SKOrderedNotOrdered;
}
NSCharacterSet *numericalCharSet = [NSCharacterSet characterSetWithCharactersInString:@".0123456789"];
NSString *vOneTrimmed = [vOne stringByTrimmingCharactersInSet:numericalCharSet];
NSString *vTwoTrimmed = [vTwo stringByTrimmingCharactersInSet:numericalCharSet];
if ([vOneTrimmed length] > 0 || [vTwoTrimmed length] > 0) {
return SKOrderedNotOrdered;
}
NSArray *vOneArray = [vOne componentsSeparatedByString:@"."];
NSArray *vTwoArray = [vTwo componentsSeparatedByString:@"."];
for (NSUInteger i = 0; i < MIN([vOneArray count], [vTwoArray count]); i++) {
NSInteger vOneInt = [[vOneArray objectAtIndex:i] intValue];
NSInteger vTwoInt = [[vTwoArray objectAtIndex:i] intValue];
if (vOneInt > vTwoInt) {
return kSKOrderedDescending;
} else if (vOneInt < vTwoInt) {
return kSKOrderedAscending;
}
}
if ([vOneArray count] > [vTwoArray count]) {
for (NSUInteger i = [vTwoArray count]; i < [vOneArray count]; i++) {
if ([[vOneArray objectAtIndex:i] intValue] > 0) {
return kSKOrderedDescending;
}
}
} else if ([vOneArray count] < [vTwoArray count]) {
for (NSUInteger i = [vOneArray count]; i < [vTwoArray count]; i++) {
if ([[vTwoArray objectAtIndex:i] intValue] > 0) {
return kSKOrderedAscending;
}
}
}
return kSKOrderedSame;
}
@end
答案 14 :(得分:4)
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
// Your code here
}
当然,NSFoundationVersionNumber_iOS_6_1
必须更改为适用于您要检查的iOS版本。在测试设备是运行iOS7还是以前的版本时,我现在编写的内容可能会被大量使用。
答案 15 :(得分:3)
#define _kisiOS7 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
if (_kisiOS7) {
NSLog(@"iOS7 or greater")
}
else {
NSLog(@"Less than iOS7");
}
答案 16 :(得分:3)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
然后按如下方式添加if条件: -
if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"10.0")) {
//Your code
}
答案 17 :(得分:2)
请尝试以下代码:
NSString *versionString = [[UIDevice currentDevice] systemVersion];
答案 18 :(得分:2)
有7.0或6.0.3这样的版本,所以我们可以简单地将版本转换为数字进行比较。如果版本是7.0,只需将另一个“.0”附加到它,然后取其数值。
int version;
NSString* iosVersion=[[UIDevice currentDevice] systemVersion];
NSArray* components=[iosVersion componentsSeparatedByString:@"."];
if ([components count]==2) {
iosVersion=[NSString stringWithFormat:@"%@.0",iosVersion];
}
iosVersion=[iosVersion stringByReplacingOccurrencesOfString:@"." withString:@""];
version=[iosVersion integerValue];
对于6.0.0
if (version==600) {
// Do something
}
for 7.0
if (version==700) {
// Do something
}
答案 19 :(得分:2)
仅用于检索操作系统版本字符串值:
[[UIDevice currentDevice] systemVersion]
答案 20 :(得分:1)
我知道这是一个老问题,但有人应该在Availability.h
中提到编译时宏。此处的所有其他方法都是运行时解决方案,并且不适用于头文件,类类别或ivar定义。
对于这些情况,请使用
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_6_0
// iOS 6+ code here
#else
// Pre iOS 6 code here
#endif
h / t this回答
答案 21 :(得分:1)
使用推荐的推荐方式...如果头文件中没有定义,您可以随时使用所需IOS版本的设备在控制台上打印它。
- (BOOL) isIOS8OrAbove{
float version802 = 1140.109985;
float version8= 1139.100000; // there is no def like NSFoundationVersionNumber_iOS_7_1 for ios 8 yet?
NSLog(@"la version actual es [%f]", NSFoundationVersionNumber);
if (NSFoundationVersionNumber >= version8){
return true;
}
return false;
}
答案 22 :(得分:1)
作为yasimturks解决方案的变体,我定义了一个函数和一些枚举值而不是五个宏。我发现它更优雅,但这是一个品味问题。
用法:
if (systemVersion(LessThan, @"5.0")) ...
.h文件:
typedef enum {
LessThan,
LessOrEqual,
Equal,
GreaterOrEqual,
GreaterThan,
NotEqual
} Comparison;
BOOL systemVersion(Comparison test, NSString* version);
.m文件:
BOOL systemVersion(Comparison test, NSString* version) {
NSComparisonResult result = [[[UIDevice currentDevice] systemVersion] compare: version options: NSNumericSearch];
switch (test) {
case LessThan: return result == NSOrderedAscending;
case LessOrEqual: return result != NSOrderedDescending;
case Equal: return result == NSOrderedSame;
case GreaterOrEqual: return result != NSOrderedAscending;
case GreaterThan: return result == NSOrderedDescending;
case NotEqual: return result != NSOrderedSame;
}
}
您应该将应用的前缀添加到名称中,尤其是Comparison
类型。
答案 23 :(得分:1)
在Swift中检查iOS版本的解决方案
switch (UIDevice.currentDevice().systemVersion.compare("8.0.0", options: NSStringCompareOptions.NumericSearch)) {
case .OrderedAscending:
println("iOS < 8.0")
case .OrderedSame, .OrderedDescending:
println("iOS >= 8.0")
}
此解决方案的结论:无论您采用哪种方式检查操作系统版本号,都是不好的做法。永远不应该以这种方式硬编码依赖关系,总是检查功能,功能或类的存在。考虑一下; Apple可能会发布类的向后兼容版本,如果他们这样做,那么您建议的代码永远不会使用它,因为您的逻辑查找操作系统版本号而不是类的存在。
在Swift中检查类存在的解决方案
if (objc_getClass("UIAlertController") == nil) {
// iOS 7
} else {
// iOS 8+
}
不要使用if (NSClassFromString("UIAlertController") == nil)
,因为它在使用iOS 7.1和8.2的iOS模拟器上正常工作,但如果您使用iOS 7.1在真实设备上进行测试,您将会发现您将永远不会通过其他部分代码片段。
答案 24 :(得分:1)
#define IsIOS8 (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1)
答案 25 :(得分:0)
在项目中添加以下Swift代码,轻松访问iOS版和设备等信息。
class DeviceInfo: NSObject {
struct ScreenSize
{
static let SCREEN_WIDTH = UIScreen.main.bounds.size.width
static let SCREEN_HEIGHT = UIScreen.main.bounds.size.height
static let SCREEN_MAX_LENGTH = max(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)
static let SCREEN_MIN_LENGTH = min(ScreenSize.SCREEN_WIDTH, ScreenSize.SCREEN_HEIGHT)
}
struct DeviceType
{
static let IS_IPHONE_4_OR_LESS = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH < 568.0
static let IS_IPHONE_5 = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 568.0
static let IS_IPHONE_6 = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH >= 667.0
static let IS_IPHONE_6P = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 736.0
static let IS_IPHONE_X = UIDevice.current.userInterfaceIdiom == .phone && ScreenSize.SCREEN_MAX_LENGTH == 812.0
static let IS_IPAD = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1024.0
static let IS_IPAD_PRO = UIDevice.current.userInterfaceIdiom == .pad && ScreenSize.SCREEN_MAX_LENGTH == 1366.0
}
struct VersionType{
static let SYS_VERSION_FLOAT = (UIDevice.current.systemVersion as NSString).floatValue
static let iOS7 = (VersionType.SYS_VERSION_FLOAT < 8.0 && VersionType.SYS_VERSION_FLOAT >= 7.0)
static let iOS8 = (VersionType.SYS_VERSION_FLOAT >= 8.0 && VersionType.SYS_VERSION_FLOAT < 9.0)
static let iOS9 = (VersionType.SYS_VERSION_FLOAT >= 9.0 && VersionType.SYS_VERSION_FLOAT < 10.0)
static let iOS10 = (VersionType.SYS_VERSION_FLOAT >= 9.0 && VersionType.SYS_VERSION_FLOAT < 11.0)
}
}
答案 26 :(得分:0)
实际有效的Swift示例:
switch UIDevice.currentDevice().systemVersion.compare("8.0.0", options: NSStringCompareOptions.NumericSearch) {
case .OrderedSame, .OrderedDescending:
println("iOS >= 8.0")
case .OrderedAscending:
println("iOS < 8.0")
}
不要使用NSProcessInfo,因为它不能在8.0下工作,因此在2016年之前它几乎无用
答案 27 :(得分:0)
这是yasirmturk宏的Swift版本。希望它能帮助一些人
// MARK: System versionning
func SYSTEM_VERSION_EQUAL_TO(v: String) -> Bool {
return UIDevice.currentDevice().systemVersion.compare(v, options: NSStringCompareOptions.NumericSearch) == NSComparisonResult.OrderedSame
}
func SYSTEM_VERSION_GREATER_THAN(v: String) -> Bool {
return UIDevice.currentDevice().systemVersion.compare(v, options: NSStringCompareOptions.NumericSearch) == NSComparisonResult.OrderedDescending
}
func SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v: String) -> Bool {
return UIDevice.currentDevice().systemVersion.compare(v, options: NSStringCompareOptions.NumericSearch) != NSComparisonResult.OrderedAscending
}
func SYSTEM_VERSION_LESS_THAN(v: String) -> Bool {
return UIDevice.currentDevice().systemVersion.compare(v, options: NSStringCompareOptions.NumericSearch) == NSComparisonResult.OrderedAscending
}
func SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v: String) -> Bool {
return UIDevice.currentDevice().systemVersion.compare(v, options: NSStringCompareOptions.NumericSearch) != NSComparisonResult.OrderedDescending
}
let kIsIOS7: Bool = SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO("7")
let kIsIOS7_1: Bool = SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO("7.1")
let kIsIOS8: Bool = SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO("8")
let kIsIOS9: Bool = SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO("9")
答案 28 :(得分:0)
与这个https://stackoverflow.com/a/19903595/1937908基本相同,但功能更强大:
#ifndef func_i_system_version_field
#define func_i_system_version_field
inline static int i_system_version_field(unsigned int fieldIndex) {
NSString* const versionString = UIDevice.currentDevice.systemVersion;
NSArray<NSString*>* const versionFields = [versionString componentsSeparatedByString:@"."];
if (fieldIndex < versionFields.count) {
NSString* const field = versionFields[fieldIndex];
return field.intValue;
}
NSLog(@"[WARNING] i_system_version(%iu): field index not present in version string '%@'.", fieldIndex, versionString);
return -1; // error indicator
}
#endif
只需将上面的代码放在头文件中。
用法:
int major = i_system_version_field(0);
int minor = i_system_version_field(1);
int patch = i_system_version_field(2);
答案 29 :(得分:0)
这是一个快速版本:
struct iOSVersion {
static let SYS_VERSION_FLOAT = (UIDevice.currentDevice().systemVersion as NSString).floatValue
static let iOS7 = (Version.SYS_VERSION_FLOAT < 8.0 && Version.SYS_VERSION_FLOAT >= 7.0)
static let iOS8 = (Version.SYS_VERSION_FLOAT >= 8.0 && Version.SYS_VERSION_FLOAT < 9.0)
static let iOS9 = (Version.SYS_VERSION_FLOAT >= 9.0 && Version.SYS_VERSION_FLOAT < 10.0)
}
用法:
if iOSVersion.iOS8 {
//Do iOS8 code here
}
答案 30 :(得分:0)
float deviceOSVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
float versionToBeCompared = 3.1.3; //(For Example in your case)
if(deviceOSVersion < versionToBeCompared)
//Do whatever you need to do. Device version is lesser than 3.1.3(in your case)
else
//Device version should be either equal to the version you specified or above
答案 31 :(得分:0)
Obj-C ++ 11中的一个更通用的版本(你可以用NSString / C函数替换一些这些东西,但这不太详细。这给你两个机制.splitSystemVersion为你提供了一个包含所有部分的数组如果您只想打开主要版本(例如switch([self splitSystemVersion][0]) {case 4: break; case 5: break; }
)。
#include <boost/lexical_cast.hpp>
- (std::vector<int>) splitSystemVersion {
std::string version = [[[UIDevice currentDevice] systemVersion] UTF8String];
std::vector<int> versions;
auto i = version.begin();
while (i != version.end()) {
auto nextIllegalChar = std::find_if(i, version.end(), [] (char c) -> bool { return !isdigit(c); } );
std::string versionPart(i, nextIllegalChar);
i = std::find_if(nextIllegalChar, version.end(), isdigit);
versions.push_back(boost::lexical_cast<int>(versionPart));
}
return versions;
}
/** Losslessly parse system version into a number
* @return <0>: the version as a number,
* @return <1>: how many numeric parts went into the composed number. e.g.
* X.Y.Z = 3. You need this to know how to compare again <0>
*/
- (std::tuple<int, int>) parseSystemVersion {
std::string version = [[[UIDevice currentDevice] systemVersion] UTF8String];
int versionAsNumber = 0;
int nParts = 0;
auto i = version.begin();
while (i != version.end()) {
auto nextIllegalChar = std::find_if(i, version.end(), [] (char c) -> bool { return !isdigit(c); } );
std::string versionPart(i, nextIllegalChar);
i = std::find_if(nextIllegalChar, version.end(), isdigit);
int part = (boost::lexical_cast<int>(versionPart));
versionAsNumber = versionAsNumber * 100 + part;
nParts ++;
}
return {versionAsNumber, nParts};
}
/** Assume that the system version will not go beyond X.Y.Z.W format.
* @return The version string.
*/
- (int) parseSystemVersionAlt {
std::string version = [[[UIDevice currentDevice] systemVersion] UTF8String];
int versionAsNumber = 0;
int nParts = 0;
auto i = version.begin();
while (i != version.end() && nParts < 4) {
auto nextIllegalChar = std::find_if(i, version.end(), [] (char c) -> bool { return !isdigit(c); } );
std::string versionPart(i, nextIllegalChar);
i = std::find_if(nextIllegalChar, version.end(), isdigit);
int part = (boost::lexical_cast<int>(versionPart));
versionAsNumber = versionAsNumber * 100 + part;
nParts ++;
}
// don't forget to pad as systemVersion may have less parts (i.e. X.Y).
for (; nParts < 4; nParts++) {
versionAsNumber *= 100;
}
return versionAsNumber;
}
答案 32 :(得分:0)
试试这个
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
// do some work
}
答案 33 :(得分:-1)
我的解决方案是在实用程序类中添加一个实用程序方法(提示提示)来解析系统版本并手动补偿浮点数排序。
此外,这段代码相当简单,所以我希望它可以帮助一些新手。只需传入一个目标浮点数,然后返回一个BOOL。
在您的共享类中声明它:
(+) (BOOL) iOSMeetsOrExceedsVersion:(float)targetVersion;
这样称呼:
BOOL shouldBranch = [SharedClass iOSMeetsOrExceedsVersion:5.0101];
(+) (BOOL) iOSMeetsOrExceedsVersion:(float)targetVersion {
/*
Note: the incoming targetVersion should use 2 digits for each subVersion --
example 5.01 for v5.1, 5.11 for v5.11 (aka subversions above 9), 5.0101 for v5.1.1, etc.
*/
// Logic: as a string, system version may have more than 2 segments (example: 5.1.1)
// so, a direct conversion to a float may return an invalid number
// instead, parse each part directly
NSArray *sysVersion = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."];
float floatVersion = [[sysVersion objectAtIndex:0] floatValue];
if (sysVersion.count > 1) {
NSString* subVersion = [sysVersion objectAtIndex:1];
if (subVersion.length == 1)
floatVersion += ([[sysVersion objectAtIndex:1] floatValue] *0.01);
else
floatVersion += ([[sysVersion objectAtIndex:1] floatValue] *0.10);
}
if (sysVersion.count > 2) {
NSString* subVersion = [sysVersion objectAtIndex:2];
if (subVersion.length == 1)
floatVersion += ([[sysVersion objectAtIndex:2] floatValue] *0.0001);
else
floatVersion += ([[sysVersion objectAtIndex:2] floatValue] *0.0010);
}
if (floatVersion >= targetVersion)
return TRUE;
// else
return FALSE;
}
答案 34 :(得分:-1)
这两个流行的答案存在一些问题:
使用NSNumericSearch
比较字符串有时会产生不直观的结果(SYSTEM_VERSION_*
宏都会受此影响):
[@"10.0" compare:@"10" options:NSNumericSearch] // returns NSOrderedDescending instead of NSOrderedSame
FIX :首先规范化字符串,然后执行比较。尝试以相同的格式获得两个字符串可能很烦人。
在检查将来的版本时,无法使用基础框架版本符号
NSFoundationVersionNumber_iOS_6_1 // does not exist in iOS 5 SDK
FIX :执行两次单独的测试以确保符号存在然后比较符号。然而另一个在这里:
基础框架版本符号并非iOS版本所独有。多个iOS版本可以具有相同的框架版本。
9.2 & 9.3 are both 1242.12
8.3 & 8.4 are both 1144.17
FIX :我认为此问题无法解决
要解决这些问题,以下方法将版本号字符串视为base-10000数字(每个主要/次要/补丁组件是单个数字),并执行基本转换为十进制,以便使用整数运算符进行比较。
为了方便地比较iOS版本字符串和比较具有任意数量组件的字符串,我们添加了另外两种方法。
+ (SInt64)integerFromVersionString:(NSString *)versionString withComponentCount:(NSUInteger)componentCount
{
//
// performs base conversion from a version string to a decimal value. the version string is interpreted as
// a base-10000 number, where each component is an individual digit. this makes it simple to use integer
// operations for comparing versions. for example (with componentCount = 4):
//
// version "5.9.22.1" = 5*1000^3 + 9*1000^2 + 22*1000^1 + 1*1000^0 = 5000900220001
// and
// version "6.0.0.0" = 6*1000^3 + 0*1000^2 + 0*1000^1 + 0*1000^1 = 6000000000000
// and
// version "6" = 6*1000^3 + 0*1000^2 + 0*1000^1 + 0*1000^1 = 6000000000000
//
// then the integer comparisons hold true as you would expect:
//
// "5.9.22.1" < "6.0.0.0" // true
// "6.0.0.0" == "6" // true
//
static NSCharacterSet *nonDecimalDigitCharacter;
static dispatch_once_t onceToken;
dispatch_once(&onceToken,
^{ // don't allocate this charset every time the function is called
nonDecimalDigitCharacter = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
});
SInt64 base = 10000; // each component in the version string must be less than base
SInt64 result = 0;
SInt64 power = 0;
// construct the decimal value left-to-right from the version string
for (NSString *component in [versionString componentsSeparatedByString:@"."])
{
if (NSNotFound != [component rangeOfCharacterFromSet:nonDecimalDigitCharacter].location)
{
// one of the version components is not an integer, so bail out
result = -1;
break;
}
result += [component longLongValue] * (long long)pow((double)base, (double)(componentCount - ++power));
}
return result;
}
+ (SInt64)integerFromVersionString:(NSString *)versionString
{
return [[self class] integerFromVersionString:versionString
withComponentCount:[[versionString componentsSeparatedByString:@"."] count]];
}
+ (SInt64)integerFromiOSVersionString:(NSString *)versionString
{
// iOS uses 3-component version string
return [[self class] integerFromVersionString:versionString
withComponentCount:3];
}
它有点面向未来,因为它支持许多修订标识符(通过4位数,0-9999;更改base
来调整此范围)并且可以支持任意数量的组件(Apple似乎使用3个组件目前,例如major.minor.patch
),但可以使用componentCount
参数明确指定。请确保componentCount
和base
不会导致溢出,即确保2^63 >= base^componentCount
!
用法示例:
NSString *currentVersion = [[UIDevice currentDevice] systemVersion];
if ([Util integerFromiOSVersionString:currentVersion] >= [Util integerFromiOSVersionString:@"42"])
{
NSLog(@"we are in some horrible distant future where iOS still exists");
}
答案 35 :(得分:-4)
所有答案看起来都有点大。 我只是用:
if (SYSTEM_VERSION_GREATER_THAN(@"7.0")){(..CODE...)}
if (SYSTEM_VERSION_EQUAL_TO(@"7.0")){(..CODE...)}
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")){(..CODE...)}
if (SYSTEM_VERSION_LESS_THAN(@"7.0")){(..CODE...)}
if (SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(@"7.0")){(..CODE...)}
当然用您所需的操作系统版本替换@"7.0"
。
答案 36 :(得分:-5)
3.1.3
。