如何在 Swift 中比较两个应用程序版本字符串

本文介绍了如何在Swift中正确比较iOS应用的版本号,解决因格式不同导致的错误比较结果。通过扩展String类并实现versionCompare方法,确保版本号即使格式不一致也能正确比较。该方法包括按句点拆分版本字符串,零填充不足位数,然后进行比较,从而确保比较的准确性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

比较应用程序版本对人类来说是一项简单的任务。您可以立即知道哪个版本较新,例如,2.1.0 高于 1.0.0 和 2.0.0,但是当您尝试在代码中执行此操作时可能并不容易。您可以尝试在字符串拆分的帮助下手动执行此操作。您可能不知道的是,如果您的版本字符串具有一致的格式,您可以将其与在 Foundation 框架中构建的标准 String 方法进行比较。

版本字符串

在这篇文章中,我将重点关注 iOS 版本号。

来自CFBundleShortVersionString

发布版本号是一个由三个以句点分隔的整数组成的字符串。第一个整数表示应用程序的主要修订,例如实现新功能或主要更改的修订。第二个整数表示实现不太突出的功能的修订版。第三个整数表示维护版本修订。

 以下是一些有效的例子:

1.0
1.0.3
2.0.0

可以直接比较

extension String {
    func versionCompare(_ otherVersion: String) -> ComparisonResult {
        return self.compare(otherVersion, options: .numeric)
    }
}

但是会有问题

警告

这种compare(_:options:range:)方法有一个问题。如果版本相同但格式不同,则会给出错误的比较结果。

"1.0.0".versionCompare("1")     // .orderedDescending
"1.0.0".versionCompare("1.0")   // .orderedDescending
"1.0.0".versionCompare("1.0.")  // .orderedDescending

 

所以进行了升级:

extension String {
    /*
     例: sortValue(by:"1.2.3".versionCompare("4"))
     */
    func versionCompare(_ otherVersion: String) -> ComparisonResult {
        // https://sarunw.com/posts/how-to-compare-two-app-version-strings-in-swift/ --> 博客地址,需要翻墙
        let versionDelimiter = "."
        
        // <1> 我们按句点 ( .)拆分版本。
        var versionComponents = self.components(separatedBy: versionDelimiter) // 通过"."拆分出 版本数字的数组 ["1", "2", "3"]
        var otherVersionComponents = otherVersion.components(separatedBy: versionDelimiter) // 通过"."拆分出 版本数字的数组 ["4"]
        
        // <2> 然后,我们找到我们将零填充的数字差异。
        let zeroDiff = versionComponents.count - otherVersionComponents.count // 因为做比较必须格式相同, 位数少的用"0"补位. 此方法为了得到需要补几个"0"
        
        // <3> 如果没有区别,我们不需要做任何事情,使用 simple .compare。
        if zeroDiff == 0 {
            // Same format, compare normally
            return self.compare(otherVersion, options: .numeric)
        } else {
            //<4> 我们填充一个缺失零的数组。
            // 根据 zeroDiff的个数,添加有几个0的数组
            let zeros = Array(repeating: "0", count: abs(zeroDiff)) // ["0", "0"]
            if zeroDiff > 0 {
                // <5> 我们将零填充数组添加到具有更少周期和零的版本中
                otherVersionComponents.append(contentsOf: zeros) // 把剩余的不足位数用"0" 补齐 ["4", "0", "0"]
            } else {
                versionComponents.append(contentsOf: zeros)
            }
            
            /*
             //<6> 我们使用数组组件从组件构建我们的版本并比较它们。这次它将具有相同的周期和位数。
             // 比较类型为 .numeric
             
             详细解析:
             1. versionDelimiter = "."
                versionComponents.joined(separator: versionDelimiter) ==> "1.2.3"
                joined ==>  数组的用法, 通过 "." 把数组中元素拼接成 字符串
             2. string.compare(...., options: .numeric)
                compare(...) ==> 字符串比较, 比较的类型为数字 .numeric
             
             caseInsensitive 不区分大小写
             literal 文字
             backwards 向后
             anchored 锚定
             numeric 数字
             
             */
            return versionComponents.joined(separator: versionDelimiter)
                .compare(otherVersionComponents.joined(separator: versionDelimiter), options: .numeric)
        }
    }
}

如何使用:

        sortValue(by:"1.2.3".versionCompare("4")) // .orderedSame
//        sortValue(by:"0.0.2".versionCompare("0.0.1")) // .orderedDescending 降序
//        sortValue(by:"0.1".versionCompare("0.0.1"))   // .orderedDescending
//        sortValue(by:"0.1.0".versionCompare("0.0.1")) // .orderedDescending
//        sortValue(by:"0.2".versionCompare("0.1"))     // .orderedDescending
//        sortValue(by:"1.0.0".versionCompare("1.1"))   // .orderedAscending 升序
//        sortValue(by:"0.1.0".versionCompare("1.0.0")) // .orderedAscending
//        sortValue(by:"0.0.1".versionCompare("1.0.0")) // .orderedAscending
//        sortValue(by:"0.0.1".versionCompare("1"))     // .orderedAscending
//        sortValue(by:"1.0".versionCompare("2"))       // .orderedAscending

private func sortValue(by type: ComparisonResult) {
        switch type {
        case .orderedAscending:
            print("orderedAscending")
        case .orderedSame:
            print("orderedSame")
        case .orderedDescending:
            print("orderedDescending")
        }
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值