我想检查设备的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) { }
我怎样才能做到这一点呢?
当前回答
简单的回答是……
从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)。
其他回答
我的解决方案是向您的实用程序类(提示提示)添加一个实用程序方法来解析系统版本并手动补偿浮点数排序。
此外,这段代码相当简单,所以我希望它能帮助一些新手。简单地传入一个目标浮点数,然后返回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;
}
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
}
我总是把它们保存在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)
基本上和这个想法一样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);
快速的例子,实际工作:
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年之前几乎没用