2014年2月15日土曜日

[iOS][Objective-C]iOSのバージョン比較


どうも。

iOSのバージョンを知りたいことがある。

そんなときは、

NSString *iOSVer = [[UIDevice currentDevice] systemVersion];

とでもすれば、
NSString*で取得することが出来る。

ただし、
これを表示することなどないワケで、
取得した後、
バージョン比較なんかしたいケースの方が多い。

理想論から言えば、
バージョンに依存しないコードが望ましいワケだが、
例えばiOS6からiOS7のように、
大きな変化があった場合には、
バージョン比較による分岐をある程度は余儀なくされる。

例えばiOS7の判定をする場合に、
Appleが推奨してる的な方法だと、

    if (floor(NSFoundationVersionNumber)
        <= NSFoundationVersionNumber_iOS_6_1) {
 
  // iOS6.1以前の場合
     
    } else {
     
        // iOS7(以降)の場合
    }

というようなやり方だが、
NSFoundationVersionNumberの定義は、
直前のバージョンまでしか対応していない。
つまり、今現在でいうと、
iOS7の定義は存在しないから、
iOS7であることの判定をするために、
iOS6.1以前でないことを確認せざるを得ないし、
条件文自体がいまいち直感的でない気がする。

ということで、
自分で分かりやすい方法に。

バージョン分岐はしたくないが、
バージョン分岐をせざるを得なくなることも考慮に入れるなら、
utilのようなクラスに持っておいてもいい。

で、
過去の経験からいくと、
iOSのバージョン比較をしたい場合、
メジャーバージョンだけ分かればいいことが多い。
というのと、
NSString*では比較がめんどくさいので、
数値で取得出来るようにする。


#define IOS_VER_NOT_AVAILABLE -1

+ (int)iOSMajorVersion {
 
    NSString *iOSVer = [[UIDevice currentDevice] systemVersion];
 
    if (iOSVer == nil || [iOSVer isEqualToString:@""]) {
     
        return IOS_VER_NOT_AVAILABLE;
    }
 
    NSArray *verArray = [iOSVer componentsSeparatedByString:@"."];
 
    return [[verArray objectAtIndex:0] intValue];
}

これで、
6や7みたいな数値と直感的に比較ができる。

マイナー、マイクロまで比較したい場合には、
もっと色んな考慮が必要で、
ひとつのクラスにして、
そのクラスのメンバに比較メソッドを仕込む方が汎用的になる。
地味だけど面倒なので、
必要になったら作ればいいんじゃないかとw

メイントピックと外れますが、

アプリ自体のバージョンを管理したいなら、
info.plistのBundle Versionに設定しておいて、

NSString *appVersion = [[NSBundle mainBundle]
                                         objectForInfoDictionaryKey:@"CFBundleVersion"];

とすれば、
NSString*で取れるので、
あとはどのようにして使いたい形に持っていくか。
まぁ、
自分の経験に照らせば、
アプリのバージョンは情報として表示することの方が多いので、
NSString*で取れればそれで構わない。


それでは。
ちゃお☆


まこぴー。