SwiftでOSバージョンを確認しますか?


190

Swiftでシステム情報を確認しようとしています。私はそれがコードによって達成できることを理解しました:

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

このコードには2つの問題があります。

  1. sysDataの初期値は何ですか?この例では、おそらくsysDataがnilであるため、retValに-1が返されます。
  2. sysDataから情報を読み取るにはどうすればよいですか?

回答:


387

iOSの場合:

var systemVersion = UIDevice.current.systemVersion

OS Xの場合:

var systemVersion = NSProcessInfo.processInfo().operatingSystemVersion

ユーザーが少なくとも特定のバージョンを実行しているかどうかを確認するだけの場合は、iOSおよびOS Xで動作する次のSwift 2機能を使用することもできます。

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

ただし、OSのバージョンを確認することはお勧めしません。バージョン番号を比較するよりも、使用したい機能がデバイスで利用可能かどうかを確認することをお勧めします。 iOSの場合、上記のように、セレクターに応答するかどうかを確認する必要があります。例えば。:

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

これは目的cに対しては正しいですが、迅速にそれを行うより良い方法があります。ここで概要を説明してい
Fogmeister

2
(特定の機能をチェックするのではなく)OSバージョンを直接チェックするために私が見ることができる1つの使用法は、ユーザー間のOSバージョンの分布に関するデータを収集し、最低の展開ターゲットを決定することです。
Nicolas Miari

90

更新: 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)

50

以下のリンクから転送されたヘルパー関数を迅速に作成しました:

デバイスで実行されている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
}

31

スウィフト5

ProcessInfoバージョン情報を提供するため、拡張機能を作成する必要はありません。iOSのサンプルコードは次のとおりです。

let os = ProcessInfo().operatingSystemVersion

switch (os.majorVersion, os.minorVersion, os.patchVersion) {
case (let x, _, _) where x < 8:
    print("iOS < 8.0.0"

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:
    print("iOS >= 10.0.0")
}

リファレンス:http : //nshipster.com/swift-system-version-checking/


17

スウィフト5

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

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

func runLegacyCode() {
    // do old stuff
}

1
なぜrunNewCodeでは#available(iOS 11.0、*)が必要なのですか?
Illya Krit

1
@IllyaKritこの#available(...)ブロックは、提供されているバージョンより古いバージョンではサポートされていないコードのエラーをコンパイラが表示しないようにします。
future-adam

15

私はシンプルな使用のためにこのシングルトンを作成し、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 {
    // 👎
}

4
そのシングルトンですか?またはIOSVersionのクラス関数だけですか?シングルトンではないでしょう static let shared = IOSVersion
チャールトンプロヴァタ2017年

9

あなたが使用している場合スウィフト2を、あなたが特定のAPIを使用するOSのバージョンを確認したい、新しい可用性機能を使用することができます。

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's great.
}

これはGoogleでのswift 2 check system versionクエリに対する最初の質問なので、この回答を書きました。


7

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
}

1
スキップComparisonResultして短くすることができます。
John Pang

また、に分解UIDevice.current.systemVersion.compare(version, options: .numeric)すると、funcコードの読み取りに役立ちます。
John Pang

5

細部

  • 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

1
Doubleバージョン番号に使用する場合、たとえば、10.0999代わりに、丸めに関する潜在的な問題はありません10.1か?
mschmidt 2017年

いいえvar stringVersion = "10.0999"; print(stringVersion.toDouble!) // print 10.0999、印刷されます10.0999
Vasily Bodnarchuk '30 / 10/30

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

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

そしてチェック

if(iOS8)
{

}
else 
{
}  

4

Swift 2以降でシステムバージョン(および他の多くのバージョン)を確認する最も簡単で簡単な方法は、次のとおりです。

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

}

また、#availableこれらのバージョンを確認できます。

iOS
iOSApplicationExtension
macOS
macOSApplicationExtension
watchOS
watchOSApplicationExtension
tvOS
tvOSApplicationExtension
swift

2

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")
}

2

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アプリでこのスニペットを使用しているため、関数名を変更しています。


1

注: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        }

1

Matt Thompsonの回答に基づいて、iOS 7以降NSFoundationNumberを確認できなくなったiOS 9を含む)でSwiftObjective-cで動作するそれぞれの単体テストを使用したメソッドを次に示します。

+ (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

実際の方法は非常に短くてコンパクトであり、説明のために単体テストコードを追加したことと、それが機能することを証明したことにお気づきでしょうか。
n8tr 2015年

一目でXCTestであることに気づかなかったのは残念です。
DawnSong 2015年

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

0

WatchOSを確認したい場合も同様です。

迅速

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

Objective-C

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

0

システムの現在のバージョンを取得して分割します。したがって、メジャーバージョンとマイナーバージョンを取得できます。

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])")

0

ここで記述されているサンプルコードのほとんどは、ゼロが追加されたバージョンでは予期しない結果になります。例えば、

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

このメソッドは、iOS "10.3"で渡されたバージョン "10.3.0"ではtrueを返しません。このような結果は意味がなく、同じバージョンと見なす必要があります。正確な比較結果を取得するには、バージョン文字列のすべての数値コンポーネントを比較することを検討する必要があります。さらに、すべて大文字でグローバルメソッドを提供することは、良い方法ではありません。SDKで使用するバージョンタイプは文字列であるため、文字列の比較機能を拡張することは理にかなっています。

システムのバージョンを比較するには、次の例がすべて機能するはずです。

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でそれをチェックアウトでき ます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.