如何查看iOS版本?


848

我想检查iOS设备的版本是否大于3.1.3 尝试过的版本:

[[UIDevice currentDevice].systemVersion floatValue]

但它不起作用,我只想要一个:

if (version > 3.1.3) { }

我该如何实现?


5
主持人注:随着时间的流逝,这个问题已经积累了30多个答案。在添加新答案之前,请确保尚未提供您的解决方案。
马特

3
if #available(iOS 9, *) {}在Swift中启动Xcode 7 。if (@available(iOS 11, *)) {}在Objective-C中启动Xcode 9 。
心教堂

Answers:


1001

快速答案...


从Swift 2.0开始,您可以#available在中使用ifguard保护仅应在某些系统上运行的代码。

if #available(iOS 9, *) {}


在Objective-C中,您需要检查系统版本并进行比较。

[[NSProcessInfo processInfo] operatingSystemVersion] 在iOS 8及更高版本中。

从Xcode 9开始:

if (@available(iOS 9, *)) {}


完整答案...

在Objective-C和Swift(在极少数情况下)中,最好避免依赖操作系统版本来指示设备或OS功能。通常,有一种更可靠的方法来检查特定功能或类是否可用。

检查API是否存在:

例如,您可以使用来检查UIPopoverController当前设备上是否可用NSClassFromString

if (NSClassFromString(@"UIPopoverController")) {
    // Do something
}

对于弱链接的类,直接向该类发送消息是安全的。值得注意的是,这适用于未显式链接为“必需”的框架。对于缺少的类,表达式的计算结果为nil,不满足以下条件:

if ([LAContext class]) {
    // Do something
}

一些类(如CLLocationManagerUIDevice)提供了检查设备功能的方法:

if ([CLLocationManager headingAvailable]) {
    // Do something
}

检查符号是否存在:

有时,您必须检查常量的存在。这是在iOS 8中引入的UIApplicationOpenSettingsURLString,用于通过加载“设置”应用-openURL:。该值在iOS 8之前不存在。向该API传递nil将会崩溃,因此您必须首先确保验证常量的存在:

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)。


161
在特定情况下,需要检查系统版本。例如,在4.0中公开了几个私有的3.x类和方法,因此,如果仅检查它们的可用性,则会在3.x中得到错误的结果。此外,UIScrollViews处理缩放比例的方式在3.2及更高版本中发生了细微变化,因此您需要检查OS版本才能正确处理结果。
布拉德·拉尔森

2
iOS 3.2不出现送-viewWillAppearUISplitViewController。我的破解方法是确定是否<iOS 4.0,然后将其自己发送到Root View的Detail View Controller中-didSelectRowAtIndexPath
jww 2011年

10
您在这里需要小心一点,因为[@"10.0" compare:@"10" options:NSNumericSearch]return NSOrderedDescending可能根本不是预期的。(我可能会期望NSOrderedSame。)这至少是理论上的可能性。
SK9

是的,我刚刚遇到了需要绕开iOS 5错误的情况。 respondsToSelector等人不会做的工作-必须比较版本。
热门点击

2
随着TVos的引入,这一点变得更加重要。可见,使用9.1 SDK时,TVos将返回9.0。因此,检查类或方法(选择器)是最好的方法,此后应检查NSFoundationVersionNumber,只有在不可能的情况下,才应检查上的系统版本UIDevice
rckoenes 2015年

1055
/*
 *  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")) {
    ...
}

20
+1。我可以想到的最简单的解决方案是,将其保存在标题中,您可以在需要的地方包含它。在某些情况下,这比使用NSClassFromString检查可用性更可靠。另一个示例是在iAd中,如果您在4.2之前的版本中使用ADBannerContentSizeIdentifierPortrait,则将获得EXEC_BAD_ACCESS,但等效的ADBannerContentSizeIdentifier320x50在4.1之后已弃用。
Rab

1
我使用的另一个地方是UIPageViewController,并将样式设置为iOS6中的UIPageViewControllerTransitionStyleScroll。
保罗·

7
这在10秒钟内无效。例如,比较4.10和4.9会得出错误的结果。
pzulw

7
使用可选.0数字时,应格外小心。例如SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0.0"),在iOS 7.0上给出的结果不正确。
2013年

1
我刚刚测试过将其放入我的.pch文件中,并且效果很好(至少使用Xcode 5构建)
whyoz 2013年

253

正如建议苹果官方文档:您可以使用NSFoundationVersionNumber,从NSObjCRuntime.h头文件。

if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
    // here you go with iOS 7
}

40
+1实际上,这是这里最安全,最准确的选择。
mxcl 2013年

8
Um .. NSFoundationVersionNumber_iOS_6_1在iOS 5 SDK中不存在。
2013年

2
@Kjuly,您可以自己定义缺少的版本号:github.com/carlj/CJAMacros/blob/master/CJAMacros/CJAMacros.h(请看第102-130行)
CarlJ 2013年

3
不,您错了,NSFoundationVersionNumber_iOS_7_0不存在。但是好吧,我们可以用定义它#ifndef NSFoundationVersionNumber_iOS_7_0 #define NSFoundationVersionNumber_iOS_7_0 1047.00 #endif。为了避免搞乱那样,我去与SYSTEM_VERSION_LESS_THAN(五)宏从yasirmturk
心教堂

7
不,但是苹果会NSFoundationVersionNumber_iOS_8_0在iOS 9中添加。只需检查一下 NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1
CarlJ

111

Objective-C中启动Xcode 9 :

if (@available(iOS 11, *)) {
    // iOS 11 (or newer) ObjC code
} else {
    // iOS 10 or older code
}

Swift中启动Xcode 7 :

if #available(iOS 11, *) {
    // iOS 11 (or newer) Swift code
} else {
    // iOS 10 or older code
}

对于版本,您可以指定MAJOR,MINOR或PATCH(有关定义,请参见http://semver.org/)。例子:

  • iOS 11iOS 11.0相同的最低版本
  • iOS 10iOS 10.3iOS 10.3.1是不同的最小版本

您可以输入以下任何系统的值:

  • iOSmacOSwatchOStvOS

我的一个吊舱中获取的真实案例示例:

if #available(iOS 10.0, tvOS 10.0, *) {
    // iOS 10+ and tvOS 10+ Swift code
} else {
    // iOS 9 and tvOS 9 older code
}

文件资料


如何在Objective-C或Swift中将其反转?
Legoless

@Legolessif (...) {} else { ... }
心教堂

我可以guard在Objective-C中使用而不是让块保持打开状态并在else语句中缩进吗?
Legoless

@Legoless不,只需使用一个空if块,后跟一个else
心教堂

1
那就是我目前拥有的解决方案,只是想避免不必要的缩进和空if块。
Legoless

45

这用于检查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
}

迅捷版:

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
}

37

尝试:

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
}

2
由于@“ 3.1.3”和systemVersion都是NSString,为什么不在这里颠倒顺序并保存比较结果?即:`if([@“ 3.1.3”比较:[UIDevice currentDevice] .systemVersion选项:NSNumericSearch] == NSOrderedDescending); // OS版本> = 3.1.3 else; // OS版本<3.1.3`
Rob

3
这样做可能会使逻辑不清楚。但是,该操作应等效。
乔纳森·格林斯潘

1
在两个整数之间进行比较肯定不是很昂贵。
KPM 2012年

这真的是风格问题。消息分派的开销将大大超过额外的整数比较。
乔纳森·格林斯潘

35

首选方法

在Swift 2.0中,Apple使用了更为方便的语法(在此处了解更多信息)添加了可用性检查。现在,您可以使用更简洁的语法检查操作系统版本:

if #available(iOS 9, *) {
    // Then we are on iOS 9
} else {
    // iOS 8 or earlier
}

这比检查respondsToSelector等(Swift的新增功能)更可取。现在,如果您没有适当地保护代码,编译器将始终警告您。


迅捷版2.0

iOS 8中的新功能NSProcessInfo允许进行更好的语义版本检查。

在iOS 8及更高版本上进行部署

对于iOS 8.0或更高版本的最低部署目标,请使用NSProcessInfo operatingSystemVersionisOperatingSystemAtLeastVersion

这将产生以下结果:

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上部署

对于iOS 7.1或更低版本的最低部署目标,请使用NSStringCompareOptions.NumericSearchon 与比较 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上阅读更多内容。


9

我总是将它们保存在我的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)

大。最好将其放置在.pchXCode项目的文件中
Vaibhav Jhaveri 2015年

1
我将所有常量放入Constants.h导入到pch文件中的文件中。
塞格夫2015年

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;
  }


}

@Jef句点在版本控制中不是小数点,而是相关的。您的答案不会忽略句点,否则会失败。在版本控制中,每个句点分隔的元素都是一个整数。例如:“ 1.23.45”大于“ 1.2.345”,因为第二个元素“ 23”大于“ 2”。如果您要消除期间,它将是相同的数字。
安德烈斯·卡内拉

6

使用nv-ios-version项目(Apache许可证,版本2.0)中包含的Version类,可以轻松获取和比较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川
崎隆彦/ nv-ios-version

博客:在运行时使用Version类获取和比较iOS版本在运行时使用Version类
获取和比较iOS版本


5

使用快速忘记[[UIDevice currentDevice] systemVersion]和NSFoundationVersionNumber来检查系统版本的新方法。

我们可以使用NSProcessInfo -isOperatingSystemAtLeastVersion

     import Foundation

     let yosemite = NSOperatingSystemVersion(majorVersion: 10, minorVersion: 10, patchVersion: 0)
     NSProcessInfo().isOperatingSystemAtLeastVersion(yosemite) // false

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

4

通常,最好询问对象是否可以执行给定的选择器,而不是检查版本号来确定是否必须存在。

如果这不是一个选择,那么您在这里确实需要小心一点,因为可能根本就没有预期的[@"5.0" compare:@"5" options:NSNumericSearch]回报NSOrderedDescending。我可能NSOrderedSame在这里。这至少是一种理论上的关注,我认为这一点值得抗拒。

同样值得考虑的是版本输入错误的可能性,无法合理地比较。苹果提供了3级预定义的常量NSOrderedAscendingNSOrderedSameNSOrderedDescending但我能想到的一些事情用所谓的NSOrderedUnordered事件,我不能比较两个的事情,我想返回表示该值。

更重要的是,苹果有朝一日会扩展其三个预定义的常量以允许各种返回值,这是比较!= 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

4
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
        // Your code here
}

当然,NSFoundationVersionNumber_iOS_6_1必须将其更改为适用于您要检查的iOS版本。我现在编写的内容可能会在测试设备运行的是iOS7或更早版本时被大量使用。


4

参加聚会有点晚,但是鉴于iOS 8.0,这可能是相关的:

如果可以避免使用

[[UIDevice currentDevice] systemVersion]

而是检查是否存在方法/类/其他内容。

if ([self.yourClassInstance respondsToSelector:@selector(<yourMethod>)]) 
{ 
    //do stuff 
}

我发现它对于位置管理器很有用,我必须为iOS 8.0调用requestWhenInUseAuthorization,但该方法不适用于iOS <8



3

我知道这是一个古老的问题,但是应该有人在中提到了编译时宏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 这个答案


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
}       

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
  }

为7.0

 if (version==700) {
   // Do something
 }

仅仅删除小数点是错误的方法。考虑一个长度超过1个字符的组件,例如6.1.10。那么此算法将产生6110 > 700,这是不正确的。
ardnew

我了解到Apple不好推出新版本,但在大多数情况下,第二版本的第二个数字从未超过5,因此毫无疑问是10。这是一种特殊的方法,因此,如果要处理2个组件的大小写,则可以修改它以处理4个大小写的aswel。无论如何,此方法在iOS6或7时已被评论。iOS 9和10有更好的检查方法,即#available。
NaXir

2

试试下面的代码:

NSString *versionString = [[UIDevice currentDevice] systemVersion];


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类型。


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;
}

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")
}

此解决方案的缺点:不管使用哪种方式,都要检查OS版本号简直是一个坏习惯。永远不要以这种方式硬编码依赖项,总要检查功能,特性或类的存在。考虑一下;Apple可能会发布类的向后兼容版本,如果他们这样做了,那么您建议的代码将永远不会使用它,因为您的逻辑会寻找OS版本号,而不是该类的存在。

此信息的来源

在Swift中检查类是否存在的解决方案

if (objc_getClass("UIAlertController") == nil) {
   // iOS 7
} else {
   // iOS 8+
}

不要使用if (NSClassFromString("UIAlertController") == nil)它,因为它可以在使用iOS 7.1和8.2的iOS模拟器上正常工作,但是如果您在使用iOS 7.1的真实设备上进行测试,很遗憾,您会注意到您永远不会通过代码片段的else部分。


为什么要拒​​绝投票?该解决方案可以完美地使用Swift和任何iOS版本。特别是对类存在的检查是完美的。
King-Wizard

1
#define IsIOS8 (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1)

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;
}


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

float versionToBeCompared = 3.1.3;甚至无法编译。

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年几乎没有用


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
}

我觉得版本应该是iOSVersion像线3-6 struct iOSVersion { static let SYS_VERSION_FLOAT = (UIDevice.currentDevice().systemVersion as NSString).floatValue static let iOS7 = (iOSVersion.SYS_VERSION_FLOAT < 8.0 && iOSVersion.SYS_VERSION_FLOAT >= 7.0) static let iOS8 = (iOSVersion.SYS_VERSION_FLOAT >= 8.0 && iOSVersion.SYS_VERSION_FLOAT < 9.0) static let iOS9 = (iOSVersion.SYS_VERSION_FLOAT >= 9.0 && iOSVersion.SYS_VERSION_FLOAT < 10.0) }
卡斯托
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.