我想检查设备的iOS版本是否大于3.1.3 我尝试了以下方法:
[[UIDevice currentDevice].systemVersion floatValue]
但是不管用,我只想要一个:
if (version > 3.1.3) { }
我怎样才能做到这一点呢?
我想检查设备的iOS版本是否大于3.1.3 我尝试了以下方法:
[[UIDevice currentDevice].systemVersion floatValue]
但是不管用,我只想要一个:
if (version > 3.1.3) { }
我怎样才能做到这一点呢?
当前回答
试试下面的代码:
NSString *versionString = [[UIDevice currentDevice] systemVersion];
其他回答
这两种常见的答案存在一些问题:
Comparing strings using NSNumericSearch sometimes has unintuitive results (the SYSTEM_VERSION_* macros all suffer from this): [@"10.0" compare:@"10" options:NSNumericSearch] // returns NSOrderedDescending instead of NSOrderedSame FIX: Normalize your strings first and then perform the comparisons. could be annoying trying to get both strings in identical formats. Using the foundation framework version symbols is not possible when checking future releases NSFoundationVersionNumber_iOS_6_1 // does not exist in iOS 5 SDK FIX: Perform two separate tests to ensure the symbol exists AND THEN compare symbols. However another here: The foundation framwork versions symbols are not unique to iOS versions. Multiple iOS releases can have the same framework version. 9.2 & 9.3 are both 1242.12 8.3 & 8.4 are both 1144.17 FIX: I believe this issue is unresolvable
为了解决这些问题,下面的方法将版本号字符串处理为以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个组件,例如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");
}
Try:
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
}
我的解决方案是向您的实用程序类(提示提示)添加一个实用程序方法来解析系统版本并手动补偿浮点数排序。
此外,这段代码相当简单,所以我希望它能帮助一些新手。简单地传入一个目标浮点数,然后返回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;
}
在您的项目中添加以下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)
}
}
简单的回答是……
从Swift 2.0开始,你可以在if或guard中使用#available来保护那些只能在特定系统上运行的代码。
if #available(iOS 9, *) {} 在Objective-C中,您需要检查系统版本并进行比较。
iOS 8及以上版本[[NSProcessInfo processInfo] operatingSystemVersion]。
从Xcode 9开始:
if (@available(iOS 9, *)) {}
完整的答案是……
在Objective-C和Swift中,最好避免依赖操作系统版本作为设备或操作系统功能的指示。通常有更可靠的方法来检查特定的特性或类是否可用。
检查api的存在:
例如,你可以使用NSClassFromString检查UIPopoverController在当前设备上是否可用:
if (NSClassFromString(@"UIPopoverController")) {
// Do something
}
对于弱链接的类,直接向类发送消息是安全的。值得注意的是,这适用于没有显式链接为“Required”的框架。对于缺少的类,表达式的计算结果为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
针对旧系统的项目可以在UIDevice上使用systemVersion。苹果在他们的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)。