Как проверить версию iOS?
Я хочу проверить, если iOS
версия устройства больше чем 3.1.3
Я пробовал такие вещи, как:
[[UIDevice currentDevice].systemVersion floatValue]
но это не работает, я просто хочу:
if (version > 3.1.3) { }
Как мне этого добиться?
37 ответов
Быстрый ответ...
Начиная с Swift 2.0, вы можете использовать #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
}
Для слабо связанных классов безопасно отправлять сообщения классу напрямую. Примечательно, что это работает для фреймворков, которые явно не связаны как "Обязательные". Для отсутствующих классов выражение оценивается как ноль, выполняя условие:
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
Проекты, ориентированные на старые системы, могут использовать systemVersion
на UIDevice
, Apple использует это в своем примере кода 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).
/*
* 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")) {
...
}
В соответствии с официальными документами Apple: вы можете использовать NSFoundationVersionNumber
, от NSObjCRuntime.h
заголовочный файл
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
// here you go with iOS 7
}
Начиная Xcode 9, в Objective-C:
if (@available(iOS 11, *)) {
// iOS 11 (or newer) ObjC code
} else {
// iOS 10 or older code
}
Начиная Xcode 7, в Swift:
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
Пример реального случая взят из одного из моих модулей:
if #available(iOS 10.0, tvOS 10.0, *) {
// iOS 10+ and tvOS 10+ Swift code
} else {
// iOS 9 and tvOS 9 older code
}
Это используется для проверки совместимости версии SDK в XCode, это если у вас большая команда с разными версиями XCode или несколько проектов, поддерживающих разные SDK, которые используют один и тот же код:
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
//programming in iOS 8+ SDK here
#else
//programming in lower than iOS 8 here
#endif
Что вы действительно хотите, чтобы проверить версию iOS на устройстве. Вы можете сделать это с этим:
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) {
//older than iOS 8 code here
} else {
//iOS 8 specific code here
}
Swift версия:
if let version = Float(UIDevice.current.systemVersion), version < 9.3 {
//add lower than 9.3 code here
} else {
//add 9.3 and above code here
}
Текущие версии Swift должны использовать это:
if #available(iOS 12, *) {
//iOS 12 specific code here
} else {
//older than iOS 12 code here
}
Пытаться:
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 Apple добавила проверку доступности, используя гораздо более удобный синтаксис (подробнее здесь). Теперь вы можете проверить версию ОС с более чистым синтаксисом:
if #available(iOS 9, *) {
// Then we are on iOS 9
} else {
// iOS 8 or earlier
}
Это предпочтительнее, чем проверка respondsToSelector
и т. д. ( Что нового в Swift). Теперь компилятор всегда предупредит вас, если вы не будете правильно защищать свой код.
Pre 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 или ниже используйте сравнение с
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.
Рекомендую:
if ([[[UIDevice currentDevice] systemVersion] floatValue] > 3.13) {
; // ...
}
Я всегда храню их в своем файле 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)
+(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;
}
}
С классом Version, который содержится в проекте nv-ios-version (Apache License, версия 2.0), легко получить и сравнить версию 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-версия
TakahikoKawasaki / NV-КСН-версия
Блог: получите и сравните версию iOS во время выполнения с классом Version
Получить и сравнить версию iOS во время выполнения с классом Version
Я знаю, что это старый вопрос, но кто-то должен был упомянуть макросы времени компиляции в Availability.h
, Все остальные методы здесь являются решениями времени выполнения и не будут работать в заголовочном файле, категории классов или определении ivar.
Для этих ситуаций используйте
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_6_0
// iOS 6+ code here
#else
// Pre iOS 6 code here
#endif
ч / т этот ответ
Новый способ проверки версии системы с использованием быстрых Forget [[UIDevice currentDevice] systemVersion] и NSFoundationVersionNumber.
Мы можем использовать NSProcessInfo -isOperatingSystemAtLeastVersion
import Foundation
let yosemite = NSOperatingSystemVersion(majorVersion: 10, minorVersion: 10, patchVersion: 0)
NSProcessInfo().isOperatingSystemAtLeastVersion(yosemite) // false
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]
Немного поздно для вечеринки, но в свете iOS 8.0 это может быть актуально:
если вы можете избежать использования
[[UIDevice currentDevice] systemVersion]
Вместо этого проверьте наличие метода / класса / чего-либо еще.
if ([self.yourClassInstance respondsToSelector:@selector(<yourMethod>)])
{
//do stuff
}
Я обнаружил, что это полезно для менеджера местоположений, где мне нужно вызвать requestWhenInUseAuthorization для iOS 8.0, но метод недоступен для iOS < 8
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
// Your code here
}
Где, конечно, NSFoundationVersionNumber_iOS_6_1
должен быть изменен на соответствующий для версии iOS, которую вы хотите проверить. То, что я сейчас написал, вероятно, будет часто использоваться при тестировании устройства под управлением iOS7 или предыдущей версии.
Как правило, лучше спросить, может ли объект выполнить данный селектор, чем проверять номер версии, чтобы решить, должен ли он присутствовать.
Когда это не вариант, вы должны быть немного осторожны, потому что здесь [@"5.0" compare:@"5" options:NSNumericSearch]
возвращается NSOrderedDescending
что вполне может быть не предназначено вообще; Я мог бы ожидать NSOrderedSame
Вот. По крайней мере, это теоретическая проблема, от которой, на мой взгляд, стоит защищаться.
Стоит также рассмотреть возможность ввода неверной версии, с которой невозможно сравнивать. Apple поставляет три предопределенные константы NSOrderedAscending
, NSOrderedSame
а также NSOrderedDescending
но я могу придумать, что использовать NSOrderedUnordered
в случае, если я не могу сравнить две вещи, и я хочу вернуть значение, указывающее это.
Более того, не исключено, что Apple однажды расширит свои три предопределенные константы, чтобы разрешить множество возвращаемых значений, сравнивая их. != 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
#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
}
#define _kisiOS7 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
if (_kisiOS7) {
NSLog(@"iOS7 or greater")
}
else {
NSLog(@"Less than iOS7");
}
Попробуйте следующий код:
NSString *versionString = [[UIDevice currentDevice] systemVersion];
Существуют версии, подобные 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
}
#define IsIOS8 (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1)
В качестве варианта решения yasimturks я определил одну функцию и несколько значений enum вместо пяти макросов. Я нахожу это более элегантным, но это вопрос вкуса.
Использование:
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
тип.
Решение для проверки версии iOS в Swift
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+
}
Не использовать if (NSClassFromString("UIAlertController") == nil)
поскольку он корректно работает на симуляторе iOS с использованием iOS 7.1 и 8.2, но если вы тестируете на реальном устройстве с использованием iOS 7.1, вы, к сожалению, заметите, что вы никогда не пройдете через остальную часть фрагмента кода.
Используя рекомендованный способ... если в заголовочных файлах нет определения, вы всегда можете получить версию, распечатав ее на консоли с устройством требуемой версии IOS.
- (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;
}
По сути, та же идея, что и эта /questions/5905906/kak-proverit-versiyu-ios/5905949#5905949, но более надежная:
#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);
Более общая версия в 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;
}
Вот Swift-версия макросов yasirmturk. Надеюсь, что это помогает некоторым народам
// 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")
Быстрый пример, который действительно работает:
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 года он практически бесполезен