提问人:John 提问时间:7/27/2010 最后编辑:James WebsterJohn 更新时间:11/15/2023 访问量:529454
如何查看iOS版本?
How to check iOS version?
问:
我想检查设备的版本是否比我尝试过的版本大:iOS
3.1.3
[[UIDevice currentDevice].systemVersion floatValue]
但它不起作用,我只想要一个:
if (version > 3.1.3) { }
我怎样才能做到这一点?
答:
尝试:
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
}
评论
快速回答......
从 Swift 2.0 开始,您可以在 or 中使用来保护只能在某些系统上运行的代码。#available
if
guard
if #available(iOS 9, *) {}
在 Objective-C 中,您需要检查系统版本并进行比较。
[[NSProcessInfo processInfo] operatingSystemVersion]
在 iOS 8 及更高版本中。
从 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 中随着 的引入而出现,用于通过 加载设置应用程序。该值在 iOS 8 之前不存在。将 nil 传递给此 API 会崩溃,因此您必须首先注意验证常量是否存在:UIApplicationOpenSettingsURLString
-openURL:
if (&UIApplicationOpenSettingsURLString != NULL) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
}
与操作系统版本比较:
假设您面临着相对罕见的检查操作系统版本的需求。对于面向 iOS 8 及更高版本的项目,包括一种执行版本比较的方法,出错几率较小:NSProcessInfo
- (BOOL)isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion)version
面向旧系统的项目可以在 上使用。Apple 在其 GLSprite 示例代码中使用它。systemVersion
UIDevice
// 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;
}
如果出于某种原因,您认为这是您想要的,请确保将其视为字符串,否则您可能会截断补丁修订号(例如 3.1.2 -> 3.1)。systemVersion
评论
-viewWillAppear
UISplitViewController
-didSelectRowAtIndexPath
[@"10.0" compare:@"10" options:NSNumericSearch]
NSOrderedDescending
NSOrderedSame
respondsToSelector
NSFoundationVersionNumber
,只有在不可能的情况下,才应检查系统版本。UIDevice
/*
* 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")) {
...
}
评论
.0
SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0.0")
通常,最好询问对象是否可以执行给定的选择器,而不是检查版本号来决定它是否必须存在。
当这不是一个选项时,您确实需要在这里小心一点,因为返回可能根本不是故意的;我可能会在这里期待。这至少是一个理论上的问题,在我看来值得辩护。[@"5.0" compare:@"5" options:NSNumericSearch]
NSOrderedDescending
NSOrderedSame
同样值得考虑的是,无法合理地与之进行比较的错误版本输入的可能性。Apple 提供了三个预定义的常量,但是如果我不能比较两个东西并且我想返回一个指示这一点的值,我可以想到一些东西的用途。NSOrderedAscending
NSOrderedSame
NSOrderedDescending
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
+(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;
}
}
评论
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;
}
我的解决方案是将实用程序方法添加到实用程序类(提示提示)中,以解析系统版本并手动补偿浮点数排序。
此外,这段代码相当简单,所以我希望它对一些新手有所帮助。只需传入目标浮点数,然后返回 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;
}
使用 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 TakahikoKawasaki/nv-ios-version
博客:使用 Version 类获取和比较运行时的 iOS 版本 使用 Version 类
获取和比较运行时的 iOS 版本
正如官方 Apple 文档所建议的那样:您可以使用头文件中的 NSFoundationVersionNumber
。NSObjCRuntime.h
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
// here you go with iOS 7
}
评论
NSFoundationVersionNumber_iOS_6_1
#ifndef NSFoundationVersionNumber_iOS_7_0 #define NSFoundationVersionNumber_iOS_7_0 1047.00 #endif
NSFoundationVersionNumber_iOS_8_0
NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
// Your code here
}
当然,必须更改为适用于您要检查的iOS版本。我现在写的东西在测试设备是否运行iOS7或以前的版本时可能会被大量使用。NSFoundationVersionNumber_iOS_6_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
所有答案看起来都有点大。 我只是使用:
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"
评论
if (SYSTEM_VERSION_GREATER_THAN(@"7.0")){(..CODE...)}
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
有 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
}
评论
6.1.10
6110 > 700
请尝试以下代码:
NSString *versionString = [[UIDevice currentDevice] systemVersion];
试试这个
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
// do some work
}
评论
#define _kisiOS7 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
if (_kisiOS7) {
NSLog(@"iOS7 or greater")
}
else {
NSLog(@"Less than iOS7");
}
使用 swift Forget [[UIDevice currentDevice] systemVersion] 和 NSFoundationVersionNumber 检查系统版本的新方法。
我们可以使用 NSProcessInfo -isOperatingSystemAtLeastVersion
import Foundation
let yosemite = NSOperatingSystemVersion(majorVersion: 10, minorVersion: 10, patchVersion: 0)
NSProcessInfo().isOperatingSystemAtLeastVersion(yosemite) // false
我知道这是一个老问题,但有人应该提到 中的编译时宏。此处的所有其他方法都是运行时解决方案,在头文件、类类别或 ivar 定义中不起作用。Availability.h
对于这些情况,请使用
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0 && defined(__IPHONE_14_0)
// iOS 14+ code here
#else
// Pre iOS 14 code here
#endif
h/t 这个答案
派对有点晚了,但鉴于 iOS 8.0 的存在,这可能是相关的:
如果可以避免使用
[[UIDevice currentDevice] systemVersion]
相反,请检查是否存在方法/类/任何其他内容。
if ([self.yourClassInstance respondsToSelector:@selector(<yourMethod>)])
{
//do stuff
}
我发现它对位置管理器很有用,我必须为 iOS 8.0 调用 requestWhenInUseAuthorization,但该方法不适用于 iOS < 8
使用推荐的推荐方式...如果头文件中没有定义,则始终可以使用所需IOS versión的设备在控制台上打印版本。
- (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;
}
首选方法
在 Swift 2.0 中,Apple 使用更方便的语法添加了可用性检查(在此处阅读更多内容)。现在,您可以使用更简洁的语法检查操作系统版本:
if #available(iOS 9, *) {
// Then we are on iOS 9
} else {
// iOS 8 or earlier
}
这是检查等的首选(Swift 中的新功能)。现在,如果你没有正确保护你的代码,编译器将始终警告你。respondsToSelector
Swift 2.0 之前的版本
iOS 8 的新功能允许更好的语义版本控制检查。NSProcessInfo
在 iOS 8 及更高版本上部署
对于 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 上部署
对于 iOS 7.1 或更低版本的最低部署目标,请使用 compare with on 。
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的更多阅读。
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;
甚至无法编译。
实际有效的 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 年它几乎没用
- 在主屏幕中,点击“设置”>“常规”>“关于”。
- 您设备的软件版本应显示在此屏幕上。
- 检查版本号是否大于 。
3.1.3
评论
我总是把它们保存在我的 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)
评论
.pch
Constants.h
pch
在 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+
}
不要使用,因为它在使用 iOS 7.1 和 8.2 的 iOS 模拟器上正常工作,但如果您在使用 iOS 7.1 的真实设备上进行测试,不幸的是,您会注意到您永远不会通过代码片段的 else 部分。if (NSClassFromString("UIAlertController") == nil)
评论
#define IsIOS8 (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1)
这是一个 swift 版本:
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
}
评论
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) }
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
仅用于检索操作系统版本字符串值:
[[UIDevice currentDevice] systemVersion]
这是 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")
两个流行的答案存在一些问题:
比较字符串有时会产生不直观的结果(宏都受到此影响):
NSNumericSearch
SYSTEM_VERSION_*
[@"10.0" compare:@"10" options:NSNumericSearch] // returns NSOrderedDescending instead of NSOrderedSame
FIX:首先对字符串进行归一化,然后执行比较。尝试以相同的格式获取两个字符串可能会很烦人。
在检查将来的发行版时,无法使用 foundation framework 版本符号
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:我认为这个问题是无法解决的
为了解决这些问题,以下方法将版本号字符串视为以 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;更改以调整此范围)并且可以支持任意数量的组件(Apple 现在似乎使用 3 个组件,例如),但这可以使用参数显式指定。确保你的并且不造成溢出,即确保!base
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");
}
#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
}
在 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 11
并且是相同的最小版本iOS 11.0
iOS 10
、 是不同的最小版本iOS 10.3
iOS 10.3.1
您可以为以下任何系统输入值:
iOS
, , , , , ...(见文档)macOS
watchOS
tvOS
visionOS
从我的一个 pod 中获取的真实案例:
if #available(iOS 10.0, tvOS 10.0, *) {
// iOS 10+ and tvOS 10+ Swift code
} else {
// iOS 9 and tvOS 9 older code
}
评论
if (...) {} else { ... }
guard
else
if
else
if
在您的项目中添加下面的 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)
}
}
与这个想法基本相同,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);
评论
if #available(iOS 9, *) {}
if (@available(iOS 11, *)) {}