Проверить версию ОС в Swift?

Я пытаюсь проверить системную информацию в Swift. Я понял, что это может быть достигнуто с помощью кода:

var sysData:CMutablePointer<utsname> = nil
let retVal:CInt = uname(sysData)

У меня есть две проблемы с этим кодом:

  • Каким должно быть начальное значение sysData? Этот пример дает -1 в retVal, вероятно, потому, что sysData равен нулю.
  • Как я могу прочитать информацию из sysData?

Ответ 1

Для iOS попробуйте:

var systemVersion = UIDevice.current.systemVersion

Для OS X попробуйте:

var systemVersion = NSProcessInfo.processInfo().operatingSystemVersion

Если вы просто хотите проверить, работает ли у пользователей хотя бы определенная версия, вы также можете использовать следующую функцию Swift 2, которая работает на iOS и OS X:

if #available(iOS 9.0, *) {
    // use the feature only available in iOS 9
    // for ex. UIStackView
} else {
    // or use some work around
}

НО не рекомендуется проверять версию ОС. Лучше проверить, доступна ли на устройстве функция, которую вы хотите использовать, чем сравнение номеров версий. Для iOS, как указано выше, вы должны проверить, реагирует ли он на селектор; например:

if (self.respondsToSelector(Selector("showViewController"))) {
    self.showViewController(vc, sender: self)
} else {
    // some work around
}

Ответ 2

Обновить:
Теперь вы должны использовать новую проверку доступности, представленную в Swift 2:
Например, чтобы проверить iOS 9.0 или новее во время компиляции, используйте это:

if #available(iOS 9.0, *) {
    // use UIStackView
} else {
    // show sad face emoji
}

или может использоваться с целым методом или классом

@available(iOS 9.0, *)
func useStackView() {
    // use UIStackView
}

Для получения дополнительной информации см. Это.

Проверка времени выполнения:

если вам не нужна точная версия, но вы хотите проверить iOS 9,10 или 11, используя:

let floatVersion = (UIDevice.current.systemVersion as NSString).floatValue

РЕДАКТИРОВАТЬ: Просто нашел другой способ добиться этого:

let iOS8 = floor(NSFoundationVersionNumber) > floor(NSFoundationVersionNumber_iOS_7_1)
let iOS7 = floor(NSFoundationVersionNumber) <= floor(NSFoundationVersionNumber_iOS_7_1)

Ответ 3

Я сделал вспомогательные функции, которые были перенесены из ссылки ниже в swift:

Как мы можем программно определить, на какой версии iOS работает устройство?

func SYSTEM_VERSION_EQUAL_TO(version: String) -> Bool {
    return UIDevice.currentDevice().systemVersion.compare(version,
        options: NSStringCompareOptions.NumericSearch) == NSComparisonResult.OrderedSame
}

func SYSTEM_VERSION_GREATER_THAN(version: String) -> Bool {
    return UIDevice.currentDevice().systemVersion.compare(version,
        options: NSStringCompareOptions.NumericSearch) == NSComparisonResult.OrderedDescending
}

func SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(version: String) -> Bool {
    return UIDevice.currentDevice().systemVersion.compare(version,
        options: NSStringCompareOptions.NumericSearch) != NSComparisonResult.OrderedAscending
}

func SYSTEM_VERSION_LESS_THAN(version: String) -> Bool {
    return UIDevice.currentDevice().systemVersion.compare(version,
        options: NSStringCompareOptions.NumericSearch) == NSComparisonResult.OrderedAscending
}

func SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(version: String) -> Bool {
    return UIDevice.currentDevice().systemVersion.compare(version,
        options: NSStringCompareOptions.NumericSearch) != NSComparisonResult.OrderedDescending
}

Это можно использовать так:

SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO("7.0")

Swift 4.2

func SYSTEM_VERSION_EQUAL_TO(version: String) -> Bool {
    return UIDevice.current.systemVersion.compare(version, options: .numeric) == .orderedSame
}

func SYSTEM_VERSION_GREATER_THAN(version: String) -> Bool {
    return UIDevice.current.systemVersion.compare(version, options: .numeric) == .orderedDescending
}

func SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(version: String) -> Bool {
    return UIDevice.current.systemVersion.compare(version, options: .numeric) != .orderedAscending
}

func SYSTEM_VERSION_LESS_THAN(version: String) -> Bool {
    return UIDevice.current.systemVersion.compare(version, options: .numeric) == .orderedAscending
}

func SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(version: String) -> Bool {
    return UIDevice.current.systemVersion.compare(version, options: .numeric) != .orderedDescending
}

Ответ 4

Swift 3.0

Нам не нужно создавать расширение, так как ProcessInfo дает нам информацию о версии. Вы можете увидеть пример кода для iOS, как показано ниже.

let os = ProcessInfo().operatingSystemVersion
switch (os.majorVersion, os.minorVersion, os.patchVersion) {
case (8, 0, _):
    print("iOS >= 8.0.0, < 8.1.0")
case (8, _, _):
    print("iOS >= 8.1.0, < 9.0")
case (9, _, _):
    print("iOS >= 9.0.0")
default:
    // this code will have already crashed on iOS 7, so >= iOS 10.0
    println("iOS >= 10.0.0")
}

Ссылка: http://nshipster.com/swift-system-version-checking/

Ответ 5

Я сделал этот Singleton для простого использования, создал файл IOSVersion.swift и добавил этот код:

import UIKit

public class IOSVersion {
    class func SYSTEM_VERSION_EQUAL_TO(version: NSString) -> Bool {
        return UIDevice.currentDevice().systemVersion.compare(version,
            options: NSStringCompareOptions.NumericSearch) == NSComparisonResult.OrderedSame
    }

    class func SYSTEM_VERSION_GREATER_THAN(version: NSString) -> Bool {
        return UIDevice.currentDevice().systemVersion.compare(version as String,
            options: NSStringCompareOptions.NumericSearch) == NSComparisonResult.OrderedDescending
    }

    class func SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(version: NSString) -> Bool {
        return UIDevice.currentDevice().systemVersion.compare(version as String,
            options: NSStringCompareOptions.NumericSearch) != NSComparisonResult.OrderedAscending
    }

    class func SYSTEM_VERSION_LESS_THAN(version: NSString) -> Bool {
        return UIDevice.currentDevice().systemVersion.compare(version as String,
            options: NSStringCompareOptions.NumericSearch) == NSComparisonResult.OrderedAscending
    }

    class func SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(version: NSString) -> Bool {
        return UIDevice.currentDevice().systemVersion.compare(version as String,
            options: NSStringCompareOptions.NumericSearch) != NSComparisonResult.OrderedDescending
    }
}

ИСПОЛЬЗОВАНИЕ:

IOSVersion.SYSTEM_VERSION_EQUAL_TO("8.0")
IOSVersion.SYSTEM_VERSION_LESS_THAN("8.0")

Спасибо @KVISH

Изменить Swift 2:

if #available(iOS 9.0, *) {
    // 👍 
} else {
    // 👎
}

Ответ 6

Swift 4

func run() {
    let version = OperatingSystemVersion(majorVersion: 11, minorVersion: 0, patchVersion: 0)
    if ProcessInfo.processInfo.isOperatingSystemAtLeast(version) {
        runNewCode()
    } else {
        runLegacyCode()
    }
}

func runNewCode() {
    guard #available(iOS 11.0, *) else {
        fatalError()
    }
    // do new stuff
}

func runLegacyCode() {
    // do old stuff
}

Ответ 7

Если вы используете Swift 2 и хотите проверить версию ОС на использование определенного API, вы можете использовать новую функцию доступности:

if #available(iOS 8, *) {
    //iOS 8+ code here.
}
else {
    //Code for iOS 7 and older versions.
    //An important note: if you use #availability, Xcode will also 
    //check that you don't use anything that was introduced in iOS 8+
    //inside this `else` block. So, if you try to use UIAlertController
    //here, for instance, it won't compile. And it great.
}

Я написал этот ответ, потому что это первый вопрос в Google для запроса swift 2 check system version.

Ответ 8

Обновление для Swift 3.0 +

func SYSTEM_VERSION_EQUAL_TO(version: String) -> Bool {
    return UIDevice.current.systemVersion.compare(version, options: .numeric) == ComparisonResult.orderedSame
}

func SYSTEM_VERSION_GREATER_THAN(version: String) -> Bool {
    return UIDevice.current.systemVersion.compare(version, options: .numeric) == ComparisonResult.orderedDescending
}

func SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(version: String) -> Bool {
    return UIDevice.current.systemVersion.compare(version, options: .numeric) != ComparisonResult.orderedAscending
}

func SYSTEM_VERSION_LESS_THAN(version: String) -> Bool {
    return UIDevice.current.systemVersion.compare(version, options: .numeric) == ComparisonResult.orderedAscending
}

func SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(version: String) -> Bool {
    return UIDevice.current.systemVersion.compare(version, options: .numeric) != ComparisonResult.orderedDescending
}

Ответ 9

let Device = UIDevice.currentDevice()
let iosVersion = NSString(string: Device.systemVersion).doubleValue

let iOS8 = iosVersion >= 8
let iOS7 = iosVersion >= 7 && iosVersion < 8

и проверьте как

if(iOS8)
{

}
else 
{
}  

Ответ 10

Самый простой и простой способ проверить версию системы (и множество других версий) в Swift 2 и выше:

if #available(iOS 9.0, *) { // check for iOS 9.0 and later

}

Кроме того, с помощью #available вы можете проверить их версии:

iOS
iOSApplicationExtension
macOS
macOSApplicationExtension
watchOS
watchOSApplicationExtension
tvOS
tvOSApplicationExtension
swift

Ответ 11

подробности

  • Xcode 10.2.1 (10E1001), Swift 5

связи

OperatingSystemVersion

Решение

extension OperatingSystemVersion {
    func getFullVersion(separator: String = ".") -> String {
        return "\(majorVersion)\(separator)\(minorVersion)\(separator)\(patchVersion)"
    }
}

let os = ProcessInfo().operatingSystemVersion
print(os.majorVersion)          // 12
print(os.minorVersion)          // 2
print(os.patchVersion)          // 0
print(os.getFullVersion())      // 12.2.0

Ответ 12

Mattt Thompson предлагает очень удобный способ

switch UIDevice.currentDevice().systemVersion.compare("8.0.0", options: NSStringCompareOptions.NumericSearch) {
case .OrderedSame, .OrderedDescending:
    println("iOS >= 8.0")
case .OrderedAscending:
    println("iOS < 8.0")
}

Ответ 13

Swift 4.x

func iOS_VERSION_EQUAL_TO(version: String) -> Bool {
    return UIDevice.current.systemVersion.compare(version, options: NSString.CompareOptions.numeric) == ComparisonResult.orderedSame
}

func iOS_VERSION_GREATER_THAN(version: String) -> Bool {
    return UIDevice.current.systemVersion.compare(version, options: NSString.CompareOptions.numeric) == ComparisonResult.orderedDescending
}

func iOS_VERSION_GREATER_THAN_OR_EQUAL_TO(version: String) -> Bool {
    return UIDevice.current.systemVersion.compare(version, options: NSString.CompareOptions.numeric) != ComparisonResult.orderedAscending
}

func iOS_VERSION_LESS_THAN(version: String) -> Bool {
    return UIDevice.current.systemVersion.compare(version, options: NSString.CompareOptions.numeric) == ComparisonResult.orderedAscending
}

func iOS_VERSION_LESS_THAN_OR_EQUAL_TO(version: String) -> Bool {
    return UIDevice.current.systemVersion.compare(version, options: NSString.CompareOptions.numeric) != ComparisonResult.orderedDescending
}

Использование:

if iOS_VERSION_GREATER_THAN_OR_EQUAL_TO(version: "11.0") {
    //Do something!
}

PS KVISH ответ переведен на Swift 4.x с переименованием функций, так как я специально использую этот фрагмент для приложения iOS.

Ответ 14

Примечание. Доступно в iOS 8.0 и более поздних версиях. OS X v10.10 и более поздние версии

var majorVersion: Int    { return NSProcessInfo.processInfo().operatingSystemVersion.majorVersion }
var minorVersion: Int    { return NSProcessInfo.processInfo().operatingSystemVersion.minorVersion }
var patchVersion: Int    { return NSProcessInfo.processInfo().operatingSystemVersion.patchVersion }
var myOSVersion:  String { return NSProcessInfo.processInfo().operatingSystemVersionString        }

Ответ 15

На основании ответа Мэтта Томпсона, вот метод с соответствующими модульными тестами, который работает с Swift и Objective-c на iOS 7 и выше (включая iOS 9, который больше не позволяет вам проверить NSFoundationNumber):

+ (BOOL) isAtLeastOSVersion:(NSString *)osVersion
{
    switch ([[UIDevice currentDevice].systemVersion compare:osVersion options:NSNumericSearch]) {
        case NSOrderedSame:
        case NSOrderedDescending:
            return YES;
        default:
            return NO;
    }
}  

.

@interface ANFakeCurrDevice : NSObject
@property (nonatomic, strong) NSString *systemVersion;
@end
@implementation ANFakeCurrDevice
@end


@implementation MyHelperClassUnitTests

- (void)setUp {
    [super setUp];
}

- (void)tearDown {
    [super tearDown];
}

- (void)test_isAtLeastOSVersion
{
    id deviceMock = [OCMockObject niceMockForClass:[UIDevice class]];
    ANFakeCurrDevice *fakeCurrDevice = [ANFakeCurrDevice new];
    fakeCurrDevice.systemVersion = @"99.9.9";
    [[[deviceMock stub] andReturn:fakeCurrDevice] currentDevice];
    XCTAssertTrue([[UIDevice currentDevice].systemVersion isEqualToString:@"99.9.9"]);

    fakeCurrDevice.systemVersion = @"1.0.1";
    XCTAssertTrue([ANConstants isAtLeastOSVersion:@"1"]);
    XCTAssertTrue([ANConstants isAtLeastOSVersion:@"1.0"]);
    XCTAssertTrue([ANConstants isAtLeastOSVersion:@"1.0.1"]);
    XCTAssertFalse([ANConstants isAtLeastOSVersion:@"1.0.2"]);
    XCTAssertFalse([ANConstants isAtLeastOSVersion:@"1.1.0"]);
    XCTAssertFalse([ANConstants isAtLeastOSVersion:@"2"]);
    XCTAssertFalse([ANConstants isAtLeastOSVersion:@"2.0"]);
    XCTAssertFalse([ANConstants isAtLeastOSVersion:@"2.0.0"]);
    XCTAssertFalse([ANConstants isAtLeastOSVersion:@"2.0.1"]);
    XCTAssertFalse([ANConstants isAtLeastOSVersion:@"2.1.0"]);


    fakeCurrDevice.systemVersion = @"8.4.0";
    XCTAssertTrue([ANConstants isAtLeastOSVersion:@"7.0.1"]);
    XCTAssertTrue([ANConstants isAtLeastOSVersion:@"8"]);
    XCTAssertTrue([ANConstants isAtLeastOSVersion:@"8.4"]);
    XCTAssertFalse([ANConstants isAtLeastOSVersion:@"8.4.1"]);
    XCTAssertFalse([ANConstants isAtLeastOSVersion:@"8.4.2"]);
    XCTAssertFalse([ANConstants isAtLeastOSVersion:@"9.0"]);
    XCTAssertFalse([ANConstants isAtLeastOSVersion:@"9.0.1"]);
    XCTAssertFalse([ANConstants isAtLeastOSVersion:@"9.0.2"]);
    XCTAssertTrue([ANConstants isAtLeastOSVersion:@"8.4"] && ![ANConstants isAtLeastOSVersion:@"9.0"]);

    fakeCurrDevice.systemVersion = @"8.4.1";
    XCTAssertTrue([ANConstants isAtLeastOSVersion:@"8.4"] && ![ANConstants isAtLeastOSVersion:@"9.0"]);
}


@end

Ответ 16

Также, если вы хотите проверить WatchOS.

Свифта

let watchOSVersion = WKInterfaceDevice.currentDevice().systemVersion
print("WatchOS version: \(watchOSVersion)")

Objective-C

NSString *watchOSVersion = [[WKInterfaceDevice currentDevice] systemVersion];
NSLog(@"WatchOS version: %@", watchOSVersion);

Ответ 17

let osVersion = NSProcessInfo.processInfo().operatingSystemVersion
let versionString = osVersion.majorVersion.description + "." + osVersion.minorVersion.description + "." + osVersion.patchVersion.description
print(versionString)

Ответ 18

Получить текущую версию системы и разделить ее.  Таким образом, вы можете получить основную и второстепенную версию.

let sys_version = UIDevice.current.systemVersion
let all_version = sys_version.components(separatedBy: ".")
print("Major version : \(all_version[0])")
print("Minor version : \(all_version[1])")

Ответ 19

Большинство примеров кода, написанных здесь, получат неожиданный результат с лишними версиями. Например,

func SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(version: String) -> Bool {
return UIDevice.current.systemVersion.compare(version, options: .numeric) != ComparisonResult.orderedAscending
}

Этот метод не вернет true с переданной версией "10.3.0" в iOS "10.3". Такой результат не имеет смысла, и их следует рассматривать как одну и ту же версию. Чтобы получить точный результат сравнения, мы должны рассмотреть возможность сравнения всех числовых компонентов в строке версии. Кроме того, предоставление глобальных методов во всех прописных буквах не является хорошим способом. Поскольку тип версии, который мы используем в нашем SDK, является строкой, имеет смысл расширить возможности сравнения в String.

Чтобы сравнить версию системы, все следующие примеры должны работать.

XCTAssertTrue(UIDevice.current.systemVersion.isVersion(lessThan: "99.0.0"))
XCTAssertTrue(UIDevice.current.systemVersion.isVersion(equalTo: UIDevice.current.systemVersion))
XCTAssertTrue(UIDevice.current.systemVersion.isVersion(greaterThan: "3.5.99"))
XCTAssertTrue(UIDevice.current.systemVersion.isVersion(lessThanOrEqualTo: "10.3.0.0.0.0.0.0"))
XCTAssertTrue(UIDevice.current.systemVersion.isVersion(greaterThanOrEqualTo: "10.3"))

Вы можете проверить это в моем репозитории здесь https://github.com/DragonCherry/VersionCompare