比较应用程序版本对于人类来说是一项简单的任务。你可以立即判断哪个版本较新,例如 2.1.0 高于 1.0.0 和 2.0.0,但当我们尝试在 swift 代码中执行此操作时可能并不容易。今天来说几种常用的比较方式。
在苹果的应用程序中,版本号是由三个句点分隔的整数组成的字符串。第一个整数表示应用程序的主要修订,例如实现新功能或主要更改的修订。第二个整数表示实现不太突出的功能的修订版。第三个整数表示维护版本修订,比如修复 bug。
方法一
Foundation 框架中提供了字符串对比的函数 compare,利用这种方式可以直接将两个字符串版本进行比较,我写了一个字符串的扩展,来实现简单的对比:
extension String {
func versionCompare(_ otherVersion: String) -> ComparisonResult {
return self.compare(otherVersion, options: .numeric)
}
}
这个方法返回一个 ComparisonResult 对象,它有三个值:
-
orderedAscending:前者小于后者
-
orderedSame:两者相等
-
orderedDescending:前者大于后者
可以这样使用:
let result = "1.0.1".versionCompare("1.0.0")
switch result {
case .orderedAscending:
print("1.0.1 < 1.0.0")
case .orderedSame:
print("1.0.1 = 1.0.0")
case .orderedDescending:
print("1.0.1 > 1.0.0")
}
最终打印:1.0.1 > 1.0.0
这种比较方式有个问题,只能对比相同位数的版本号,如果是一个两位,一个三位,比如 1.0 和 1.0.0 对比,就无法得出正确结果了。
方法二
要解决上边的问题,需要我们把这个扩展再改改:
extension String {
func versionCompare(_ otherVersion: String) -> ComparisonResult {
var v1 = versionComponents()
var v2 = otherVersion.versionComponents()
let diff = v1.count - v2.count
if diff == 0 {
return self.compare(otherVersion, options: .numeric)
}
if diff > 0 {
v2.append(contentsOf: (0..<diff).map { _ in "0" })
} else {
v1.append(contentsOf: (0..<abs(diff)).map { _ in "0" })
}
return v1.joined().compare(v2.joined())
}
func versionComponents() -> [String] {
components(separatedBy: ".")
}
}
1、首先把两个版本号按句点( . )拆分成数组
2、对比两个版本号的长度是否一致,如果一致,则利用 compare 函数直接对比
3、如果不一致,则把较短的版本号后面补 0
4、最后再用 compare 函数进行对比
最后我又写了一些测试用例,确保它能对比各种情况的版本号:
print("0.1.1".versionCompare("0.1") == .orderedDescending) // true
print("0.1.0".versionCompare("0.1") == .orderedSame) // true
print("10.0.0".versionCompare("10") == .orderedSame) // true
print("10.0.1".versionCompare("10.0.1") == .orderedSame) // true
print("5.10.10".versionCompare("5.11.5") == .orderedAscending) // true
print("1.0.0".versionCompare("0.99.100") == .orderedDescending) // true
print("0.5.3".versionCompare("1.0.0") == .orderedAscending) // true
print("0.5.29".versionCompare("0.5.3") == .orderedDescending) // true
print("1.0".versionCompare("1.0.0.0.0.0") == .orderedSame) // true
最终以上测试用例全部符合预期。
本文同步自微信公众号 “iOS新知”,每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!