【iOS】OSのバージョン確認用のメソッド


以下を参考にさせていただきました。

[[iOS 8] NSProcessInfo で iOS のバージョンを判定する ｜ Developers.IO](http://dev.classmethod.jp/references/ios8-version-distinction/)

`Objective-C`, `Swift1.2`, `Swift2.0`で書いてみました。

## Objective-C

```objc:Util.h
#import <Foundation/Foundation.h>

@interface Util : NSObject

/**
 * デバイスのOSバージョンが指定したバージョン以上かどうかを確認してBOOLで返す
 * @param   majorVersion    メジャーバージョン
 * @param   minorVersion    マイナーバージョン
 * @param   patchVersion    バッジバージョン
 * @return  BOOL            引数で渡したOSバージョン以上だった場合,YES　それより下の場合はNO
 */
+ (BOOL)greaterThanOrEqualMajorVersion:(NSInteger)majorVersion minorVersion:(NSInteger)minorVersion patchVersion:(NSInteger)patchVersion;

/**
 * 引数のversionNumberを一番短い数字にして返す
 * @param    versionNumber    "0.0.0"みたいな数字
 * @return    ".0"をなくした数字のNSString
 */
+ (NSString * _Nonnull)shortedVersionNumber:(NSString * _Nonnull)versionNumber;

@end
```

```objc:Util.m
#import "Util.h"

@implementation Util

+ (BOOL)greaterThanOrEqualMajorVersion:(NSInteger)majorVersion minorVersion:(NSInteger)minorVersion patchVersion:(NSInteger)patchVersion {
    
    if (NSClassFromString(@"NSProcessInfo") && [[NSProcessInfo processInfo] respondsToSelector:@selector(isOperatingSystemAtLeastVersion:)]) {
        NSOperatingSystemVersion version = {majorVersion, minorVersion, patchVersion};
        return [[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:version];
    }
    
    NSString *targetVersion = [self shortedVersionNumber:[NSString stringWithFormat:@"%d.%d.%d", (int)majorVersion, (int)minorVersion, (int)patchVersion]];
    NSString *systemVersion = [self shortedVersionNumber:[UIDevice currentDevice].systemVersion];
    return [systemVersion compare:targetVersion options:NSNumericSearch] != NSOrderedAscending;
}

+ (NSString * _Nonnull)shortedVersionNumber:(NSString * _Nonnull)versionNumber {
    static NSString *suffix = @".0";
    NSString *shortedVersion = versionNumber;
    while ([shortedVersion hasSuffix:suffix]) {
        NSInteger endIndex = shortedVersion.length - suffix.length;
        NSRange range = NSMakeRange(0, endIndex);
        shortedVersion = [shortedVersion substringWithRange:range];
    }
    return shortedVersion;
}

@end
```

## Swift 1.2

```swift:Util.swift
class func greaterThanOrEqual(#majorVersion: Int, minorVersion: Int, patchVersion: Int) -> Bool {
    if NSProcessInfo().respondsToSelector("isOperatingSystemAtLeastVersion:") {
        let version = NSOperatingSystemVersion(majorVersion: majorVersion, minorVersion: minorVersion, patchVersion: patchVersion)
        return NSProcessInfo().isOperatingSystemAtLeastVersion(version)
    }
    let targetVersion = shortedVersionNumber("\(majorVersion).\(minorVersion).\(patchVersion)")
    let systemVersion: String = shortedVersionNumber(UIDevice.currentDevice().systemVersion)
    return systemVersion.compare(targetVersion, options: .NumericSearch) != NSComparisonResult.OrderedAscending
}
    
class func shortedVersionNumber(versionNumber: String) -> String {
    let suffix = ".0"
    var shortedVersion  = versionNumber
    while shortedVersion.hasPrefix(suffix) {
        let endIndex = count(shortedVersion) - count(suffix)
        let range = Range(start: advance(shortedVersion.startIndex, 0), end: advance(shortedVersion.startIndex, endIndex))
        shortedVersion = shortedVersion.substringWithRange(range)
    }
    return shortedVersion
}
```

## Swift 2.0

```swift:Util.swift
class func greaterThanOrEqual(#majorVersion: Int, minorVersion: Int, patchVersion: Int) -> Bool {
    if NSProcessInfo().respondsToSelector("isOperatingSystemAtLeastVersion:") {
        let version = NSOperatingSystemVersion(majorVersion: majorVersion, minorVersion: minorVersion, patchVersion: patchVersion)
        return NSProcessInfo().isOperatingSystemAtLeastVersion(version)
    }
    let targetVersion = shortedVersionNumber("\(majorVersion).\(minorVersion).\(patchVersion)")
    let systemVersion: String = shortedVersionNumber(UIDevice.currentDevice().systemVersion)
    return systemVersion.compare(targetVersion, options: .NumericSearch) != NSComparisonResult.OrderedAscending
}
    
class func shortedVersionNumber(versionNumber: String) -> String {
    let suffix = ".0"
    var shortedVersion  = versionNumber
    while shortedVersion.hasSuffix(suffix) {
        let endIndex = shortedVersion.characters.count - suffix.characters.count
        let range = Range(start: advance(shortedVersion.startIndex, 0), end: advance(shortedVersion.startIndex, endIndex))
        shortedVersion = shortedVersion.substringWithRange(range)
    }
    return shortedVersion
}
```

## 補足

**iOS8**以上の場合は`NSProcessInfo`で簡単に判別できます。

ただ今回のプロジェクトでまだ **iOS7**を捨てられなかったため、上記のようなメソッドを用意しました。

`NSProcessInfo`について詳しく知りたければ、以下のリファレンスを読んでください。

[NSProcessInfo Class Reference](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSProcessInfo_Class/)

ただそろそろ **iOS7**を切り捨てていい命令が出ることだと思うので、いらなくなるなという気持ちとこんな面倒なこともしなきゃいけなかったんだよ的な気持ちで記事にしました。

以上になります。