LoginSignup
2
3

More than 3 years have passed since last update.

Swift アプリのバージョン比較(Swift5.3対応)

Last updated at Posted at 2019-01-30

新しいバージョンを確認するためのダイアログ機能を出すなどの処理を追加するにあたって、「Swift バージョン比較」で検索した時に見つかる記事が正しく動作しないので、動作するものを作りました。

2020-11-02 追記
用途が「古いバージョンから新しいバージョンを比較する」という限定的なものだったので間違ったコードが載っていました。
components関数が消えていたのでメンテナンスも兼ねてアップデートしています。

  • 1.01.0.1`
    • 1.0.1の方が新しい
  • 109
    • 10の方が新しい

条件は概ねこのような形ですが、NSComparisonResultを使った形だとうまく動作しません。

print("11".compare("10") == .orderedDescending)
-> true (ok)

print("9".compare("8") == .orderedDescending)
-> true (ok)

print("10".compare("9") == .orderedDescending)
-> false (ng)

解決策

正しくバージョンを比較するには「.」で分割し、先頭から順に数値でチェックする必要があります。

extension String {

    func compareVersionText(_ target : String) -> Bool{

        let v1 = self.split(separator: ".")
        let v2 = target.split(separator: ".")

        //個数が揃わない場合もあるので、チェックする数は統一する
        let count = max(v1.count, v2.count)

        for i in 0..<count {

            let vv1 = (v1.count > i) ? v1[i] : "0"
            let vv2 = (v2.count > i) ? v2[i] : "0"

            //数値でチェックする(数値でチェックできないものは0として扱う)
            let vv1num = Int(vv1) ?? 0
            let vv2num = Int(vv2) ?? 0

            //vv2の方が大きい時点で処理を中断
            if vv1num < vv2num {
                return true
            }

            //vv1の方が大きい時点で処理を中断
            if vv1num > vv2num {
                return false
            }
        }

        //最後まで進んだ場合はfalse(バージョンが一致している)
        return false
    }

}

使い方

if "1.0".compareVersionText("1.0.1") {
   print("it's new version")
}

検証用コード

func testPrint(_ expect : Bool, _ target : Bool){
    let formated = String(
        format: "%@ %@",
        arguments: [
            (expect) ? "true" : "false",
            (target) ? "true" : "false"
        ]
    )
    print(formated)
}

testPrint(true, "1.0".compareVersionText("1.0.1"))
testPrint(true, "1.0".compareVersionText("1.1"))
testPrint(true, "1.0.0".compareVersionText("1.0.1"))
testPrint(true, "1.0.0".compareVersionText("1.1.1"))
testPrint(true, "1.0.0".compareVersionText("10.0.0"))
testPrint(true, "8".compareVersionText("10"))
testPrint(true, "8".compareVersionText("10.1"))
testPrint(true, "1.9.0".compareVersionText("1.10.0"))

//先頭がお大きいバージョン
testPrint(true, "1.10.0".compareVersionText("2.0.0"))
testPrint(false, "2.0.0".compareVersionText("1.10.0"))

//同じバージョン
testPrint(false, "1.0".compareVersionText("1.0"))

//一桁テスト
testPrint(false, "10".compareVersionText("9"))
testPrint(false, "100".compareVersionText("99"))

■ 結果

true true
true true
true true
true true
true true
true true
true true
true true
true true
false false
false false
false false
false false

参考 https://qiita.com/kazuman519/items/fd142219630f758d8fcf

2
3
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3