我想检查设备的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://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);
其他回答
一般来说,最好是询问一个对象是否可以执行给定的选择器,而不是检查版本号来决定它是否必须存在。
当这不是一个选项,你需要在这里有点小心,因为[@"5.0"比较:@"5"选项:NSNumericSearch]返回nsordereddescent这可能不是有意的;我可能期待NSOrderedSame。这至少是一个理论上的问题,在我看来,这是一个值得防范的问题。
同样值得考虑的是,可能会出现无法合理比较的糟糕版本输入。苹果提供了三个预定义的常量NSOrderedAscending, NSOrderedSame和nsordereddescent,但我可以想到一个叫做NSOrderedUnordered的东西的使用,在我不能比较两个东西的情况下,我想返回一个值来指示这个。
更重要的是,苹果有一天会扩展他们的三个预定义常量以允许各种返回值,这是不可能的,这使得比较不明智。
考虑下面的代码。
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
在您的项目中添加以下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)
}
}
有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];
为0
if (version==600) {
// Do something
}
为7.0
if (version==700) {
// Do something
}
一个在obj - c++ 11中更通用的版本(你可能会用NSString/C函数替换其中的一些东西,但这不是那么冗长。这给了你两种机制。splitSystemVersion为你提供了一个包含所有部分的数组,如果你只是想打开主版本(例如switch([self splitSystemVersion][0]) {case 4: break;案例5:断裂;})。
#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;
}
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
}