我想检查设备的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) { }
我该如何实现这个?
基本上与这个想法https://dev59.com/yXA75IYBdhLWcg3wW3oZ#19903595相同,但更加健壮:
#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);
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)
}
}
我的解决方案是在你的工具类(提示提示)中添加一个实用方法来解析系统版本并手动补偿浮点数排序。
此外,这段代码相当简单,所以我希望它能帮助一些新手。只需传入目标浮点数,就可以得到一个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;
}
这两个流行答案存在一些问题:
使用 NSNumericSearch
比较字符串有时会产生令人费解的结果(所有的 SYSTEM_VERSION_*
宏都受到此影响):
[@"10.0" compare:@"10" options:NSNumericSearch] // 返回 NSOrderedDescending 而不是 NSOrderedSame
解决方法:首先将您的字符串规范化,然后再进行比较。尝试让两个字符串格式完全相同可能会很烦人。
在检查未来版本时,使用基础框架版本符号是不可能的。
NSFoundationVersionNumber_iOS_6_1 // 在 iOS 5 SDK 中不存在
解决方法:执行两个单独的测试以确保符号存在,然后再比较符号。但这里还有一个问题:
基础框架版本符号不是唯一的 iOS 版本。多个 iOS 发布版本可以具有相同的框架版本。
9.2 和 9.3 都是 1242.12
8.3 和 8.4 都是 1144.17
解决方法:我认为这个问题是无法解决的。
+ (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");
}
所有的答案看起来都有点太大了。 我只是使用:
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...)}
,所以它回答了问题,对吧? - HelloGoodbye#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
回答应直接与主题问题相关,并且应该清晰明了。这就是为什么它被投票否决的原因。 - Andres Canella3.1.3
。
if #available(iOS 9, *) {}
。从 Xcode 9 开始,在 Objective-C 中使用if (@available(iOS 11, *)) {}
。 - Cœur