比较Swift中的两个版本字符串

cod*_*man 56 ios swift

我有两个不同的应用程序版本字符串(即"3.0.1"和"3.0.2").

如何使用Swift比较这些?

cod*_*man 111

结束了我的字符串转换为NSStrings:

if storeVersion.compare(currentVersion, options: NSStringCompareOptions.NumericSearch) == NSComparisonResult.OrderedDescending {
       println("store version is newer")
}
Run Code Online (Sandbox Code Playgroud)

斯威夫特3

let currentVersion = "3.0.1"
let storeVersion = "3.0.2"

if storeVersion.compare(currentVersion, options: .numeric) == .orderedDescending {
    print("store version is newer")
}
Run Code Online (Sandbox Code Playgroud)

  • 重要提示:如果您决定使用 .orderedSame 检查版本号是否相等或更新,请注意以 .0 结尾的版本号。比较 2.4 和 2.4.0 将在一个方向返回 true,但在另一个方向返回 false。最好的办法是避免版本以 .0 结尾。第二个最好的事情是在比较它们之前修剪它们潜在的“.0”的版本号。 (4认同)
  • `extension String { func isVersionNewer(compareVersion: String) -> Bool { if self.compare(compareVersion, options: NSStringCompareOptions.NumericSearch) == NSComparisonResult.OrderedDescending { return true } return false }` (2认同)
  • Swift 3版本:`if storeVersion.compare(currentVersion,options:NSString.CompareOptions.numeric)== ComparisonResult.orderedDescending {NSLog("store version is newer")}` (2认同)

Dra*_*rry 32

您不需要将其强制转换为NSString.Swift 3中的String对象足以比较下面的版本.

let version = "1.0.0"
let targetVersion = "0.5.0"

version.compare(targetVersion, options: .numeric) == .orderedSame        // false
version.compare(targetVersion, options: .numeric) == .orderedAscending   // false
version.compare(targetVersion, options: .numeric) == .orderedDescending  // true
Run Code Online (Sandbox Code Playgroud)

但上面的示例并未涵盖带有额外零的版本.(例如:"1.0.0"和"1.0")

所以,我在String中制作了各种扩展方法,以便使用Swift处理版本比较.它确实考虑了我说的额外零,非常简单,并将按预期工作.

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: "13.5.99"))
XCTAssertTrue(UIDevice.current.systemVersion.isVersion(greaterThanOrEqualTo: UIDevice.current.systemVersion))
XCTAssertTrue("0.1.1".isVersion(greaterThan: "0.1"))
XCTAssertTrue("0.1.0".isVersion(equalTo: "0.1"))
XCTAssertTrue("10.0.0".isVersion(equalTo: "10"))
XCTAssertTrue("10.0.1".isVersion(equalTo: "10.0.1"))
XCTAssertTrue("5.10.10".isVersion(lessThan: "5.11.5"))
XCTAssertTrue("1.0.0".isVersion(greaterThan: "0.99.100"))
XCTAssertTrue("0.5.3".isVersion(lessThanOrEqualTo: "1.0.0"))
XCTAssertTrue("0.5.29".isVersion(greaterThanOrEqualTo: "0.5.3"))
Run Code Online (Sandbox Code Playgroud)

只需查看并在我的示例扩展存储库中获取您想要的所有内容,而无需关心许可.

https://github.com/DragonCherry/VersionCompare

  • 完美的方法,@ DragonCherry。这应该被认为是正确的答案。 (3认同)
  • 你的扩展很棒!但是,不幸的是,当版本像“1.0.1.2”时它不起作用(我知道,它应该存在,但事情发生了)。我更改了您的扩展并改进了测试以涵盖(我相信)所有情况。另外,我创建了一个扩展,从版本字符串中删除所有不必要的字符,有时它可以是“v1.0.1.2”。您可以检查以下要点中的所有代码: 字符串扩展 - https://gist.github.com/endy-s/3791fe5c856cccaabff331fd49356dbf 测试 - https://gist.github.com/endy-s/7cacaa730bf9fd5abf6021e58e962191 希望它对任何人都有帮助:) (2认同)

Wan*_*ane 20

Swift 3版

let storeVersion = "3.14.10"
let currentVersion = "3.130.10"

extension String {
    func versionToInt() -> [Int] {
        return self.components(separatedBy: ".")
            .map { Int.init($0) ?? 0 }
    }
}
//true
storeVersion.versionToInt().lexicographicallyPrecedes(currentVersion.versionToInt())
Run Code Online (Sandbox Code Playgroud)

Swift 2版比较

let storeVersion = "3.14.10"

let currentVersion = "3.130.10"
extension String {
    func versionToInt() -> [Int] {
      return self.componentsSeparatedByString(".")
          .map {
              Int.init($0) ?? 0
          }
    }
}

// true
storeVersion.versionToInt().lexicographicalCompare(currentVersion.versionToInt()) 
Run Code Online (Sandbox Code Playgroud)

  • 如果说当前版本是"2.7"并且在商店中你得到"2.7.0",这将无法正常工作 (4认同)

Ash*_*hok 9

以下是为我工作:

extension String {

  static func ==(lhs: String, rhs: String) -> Bool {
    return lhs.compare(rhs, options: .numeric) == .orderedSame
  }

  static func <(lhs: String, rhs: String) -> Bool {
    return lhs.compare(rhs, options: .numeric) == .orderedAscending
  }

  static func <=(lhs: String, rhs: String) -> Bool {
    return lhs.compare(rhs, options: .numeric) == .orderedAscending || lhs.compare(rhs, options: .numeric) == .orderedSame
  }

  static func >(lhs: String, rhs: String) -> Bool {
    return lhs.compare(rhs, options: .numeric) == .orderedDescending
  }

  static func >=(lhs: String, rhs: String) -> Bool {
    return lhs.compare(rhs, options: .numeric) == .orderedDescending || lhs.compare(rhs, options: .numeric) == .orderedSame
  }

}


"1.2.3" == "1.2.3" // true
"1.2.3" > "1.2.3" // false
"1.2.3" >= "1.2.3" // true
"1.2.3" < "1.2.3" // false
"1.2.3" <= "1.2.3" // true

"3.0.0" >= "3.0.0.1" // false
"3.0.0" > "3.0.0.1" // false
"3.0.0" <= "3.0.0.1" // true
"3.0.0.1" >= "3.0.0.1" // true
"3.0.1.1.1.1" >= "3.0.2" // false
"3.0.15" > "3.0.1.1.1.1" // true
"3.0.10" > "3.0.100.1.1.1" // false
"3.0.1.1.1.3.1.7" == "3.0.1.1.1.3.1" // false
"3.0.1.1.1.3.1.7" > "3.0.1.1.1.3.1" // true

"3.14.10" == "3.130.10" // false
"3.14.10" > "3.130.10" // false
"3.14.10" >= "3.130.10" // false
"3.14.10" < "3.130.10" // true
"3.14.10" <= "3.130.10" // true
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


Pin*_*Gjr 6

斯威夫特4

let current = "1.3"
let appStore = "1.2.9"
let versionCompare = current.compare(appStore, options: .numeric)
if versionCompare == .orderedSame {
    print("same version")
} else if versionCompare == .orderedAscending {
    // will execute the code here
    print("ask user to update")
} else if versionCompare == .orderedDescending {
    // execute if current > appStore
    print("don't expect happen...")
}
Run Code Online (Sandbox Code Playgroud)


Mic*_*sen 5

我混合了 Ashok 版本和 DragonCherry:

// MARK: - Version comparison

extension String {

    // Modified from the DragonCherry extension - https://github.com/DragonCherry/VersionCompare
    private func compare(toVersion targetVersion: String) -> ComparisonResult {
        let versionDelimiter = "."
        var result: ComparisonResult = .orderedSame
        var versionComponents = components(separatedBy: versionDelimiter)
        var targetComponents = targetVersion.components(separatedBy: versionDelimiter)

        while versionComponents.count < targetComponents.count {
            versionComponents.append("0")
        }

        while targetComponents.count < versionComponents.count {
            targetComponents.append("0")
        }

        for (version, target) in zip(versionComponents, targetComponents) {
            result = version.compare(target, options: .numeric)
            if result != .orderedSame {
                break
            }
        }

        return result
    }

    func isVersion(equalTo targetVersion: String) -> Bool { return compare(toVersion: targetVersion) == .orderedSame }

    func isVersion(greaterThan targetVersion: String) -> Bool { return compare(toVersion: targetVersion) == .orderedDescending }

    func isVersion(greaterThanOrEqualTo targetVersion: String) -> Bool { return compare(toVersion: targetVersion) != .orderedAscending }

    func isVersion(lessThan targetVersion: String) -> Bool { return compare(toVersion: targetVersion) == .orderedAscending }

    func isVersion(lessThanOrEqualTo targetVersion: String) -> Bool { return compare(toVersion: targetVersion) != .orderedDescending }

    static func ==(lhs: String, rhs: String) -> Bool { lhs.compare(toVersion: rhs) == .orderedSame }

    static func <(lhs: String, rhs: String) -> Bool { lhs.compare(toVersion: rhs) == .orderedAscending }

    static func <=(lhs: String, rhs: String) -> Bool { lhs.compare(toVersion: rhs) != .orderedDescending }

    static func >(lhs: String, rhs: String) -> Bool { lhs.compare(toVersion: rhs) == .orderedDescending }

    static func >=(lhs: String, rhs: String) -> Bool { lhs.compare(toVersion: rhs) != .orderedAscending }

}
Run Code Online (Sandbox Code Playgroud)

使用:

"1.2.3" == "1.2.3" // true
"1.2.3" > "1.2.3" // false
"1.2.3" >= "1.2.3" // true
"1.2.3" < "1.2.3" // false
"1.2.3" <= "1.2.3" // true

"3.0.0" >= "3.0.0.1" // false
"3.0.0" > "3.0.0.1" // false
"3.0.0" <= "3.0.0.1" // true
"3.0.0.1" >= "3.0.0.1" // true
"3.0.1.1.1.1" >= "3.0.2" // false
"3.0.15" > "3.0.1.1.1.1" // true
"3.0.10" > "3.0.100.1.1.1" // false
"3.0.1.1.1.3.1.7" == "3.0.1.1.1.3.1" // false
"3.0.1.1.1.3.1.7" > "3.0.1.1.1.3.1" // true

"3.14.10" == "3.130.10" // false
"3.14.10" > "3.130.10" // false
"3.14.10" >= "3.130.10" // false
"3.14.10" < "3.130.10" // true
"3.14.10" <= "3.130.10" // true

"0.1.1".isVersion(greaterThan: "0.1")
"0.1.0".isVersion(equalTo: "0.1")
"10.0.0".isVersion(equalTo: "10")
"10.0.1".isVersion(equalTo: "10.0.1")
"5.10.10".isVersion(lessThan: "5.11.5")
"1.0.0".isVersion(greaterThan: "0.99.100")
"0.5.3".isVersion(lessThanOrEqualTo: "1.0.0")
"0.5.29".isVersion(greaterThanOrEqualTo: "0.5.3")
Run Code Online (Sandbox Code Playgroud)