软件的应用版本设计, 有很多做法, 因为它本身只是一种软规范, 并无一种强制规范来约束它的强制执行, 所以造成了在实际情况中, 做法多样. 在iOS应用的开发中, 我们也会遇到软件版本设计的问题. 针对iOS应用的版本设计, 我们需要有针对性的设定一种规则, 这里的针对性, 就是指实际工作中需要注意的点.
首先, 我们得考虑应用对用户的提示作用, 提升版本对用户带来的感觉变化, 这是版本升级的作用. 这是最难把握, 有些用户倾向于版本升级更快的产品, 有些用户则希望版本升级更慢, 对于前者, 我们的版本号需要升级的更快, 而对于后者, 更慢的数值提升可以给他们更多的安全感. 其中的把握, 不能太极端, 非得符合某一部分用户的体验. 但是, 一定要适当的倾向于前一种用户(希望版本升级更快), 因为这些用户本身就更倾向于玩app的体验, 在电子产品的使用上, 有更强的说服力, 所以, 适当倾向于这部分用户, 是比较合理的.
其次, 要考虑应用本身的标示作用, 早期的软件产品, 生产周期和维护周期特别长, 所以, 一般上, 大版本号的提升几乎都是慎之又慎的行为, 比如一些Linux应用, 多年时间, 一个大版本号的提升都没有, 甚至很多时候, 一些产品都要进入衰退期了, 仍然还没有到1.0版本号. 而现代的产品, 一般上要求生产周期变得非常快, 为了给用户更好的体验, 往往都会采用激进的大版本号政策, 尤其是浏览器类应用, 基本上没几个月, 大版本号都已经提了好几个了. 这其中的区别, 主要是两者的需求不同, 早期的应用开发, 本身对产品的规划时间就比较长, 尤其是瀑布式开发为主, 每次大变更, 都意味着是一次需求层的重大转折. 而现代产品的开发, 则会有另外一种模式, 每次小变革都要做一次大版的提升. 这是因为现代产品的生产周期变得很快, 如果还采用老式的版本递升模式, 很可能永远都在1.0上了, 白白的浪费了大版本号的数值.
再者, 技术团队内部的考量也是一个要素, 保持一个升级速度, 可以给团队以鼓励感. 否则, 一个长时间不提升版本的产品, 可能对团队来说 成就感会有所降低. 但同时, 也不能太快, 让团队觉得这个项目本身非常浮躁.
最后, 技术难度本身的衡量也要考虑, 很多团队, 喜欢用多层小数点来划分版本号, 对于一个规模化的团队来说, 自然是可以的, 但是, 对于小团队来说(事实上, 现在做app开发的, 都是小团队), 多层小数点, 其实就变成了一个符号而已, 我们在解析版本号的时候(用于自动升级提示之类的), 平白无故的花了工作量. 而如果只有一个小数点, 则成本小了很多, 直接转换为float类型就好(注意, 这里有一个坑, 下面会揭晓).
我为iOS应用版本的升级设置这样的规则:
- 版本号只有两层, 大版本号和小版本号, 中间通过点来分割.
- 每次更改代码重新编译, 只提升build号, 不提升版本号.
- 每次递交AppStore, 小版本号加一.
- 一旦小版本号达到10次, 大版本号加一, 小版本号回归零.
- 如果遇到产品相对比较重要的更新, 大版本号也加一.
考虑到大部分产品的生命周期内, 一年内递交的次数最多也就2,3十次的样子, 所以, 一般上, 一年内, 大版本号可以升级比较小的数字, 这样的设计, 基本上可以够我们实际开发所用了. 事实上, 现代的app产品, 越来越变成了一种快消性质的产品了, 其实用户对版本号的关注度, 只会越来越小, 在版本号的设计上, 可以更倾向于内部告知的作用, 而不是对用户的外部告知.
揭晓一下上面说的坑, 那就是版本号的设计, 并不是简单的float类型. 正常的小数点, 1.10是小于1.9的, 但是, 在版本号的标识上, 往往1.10是大于1.9的. 所以一旦出现1.10和1.9的判断, 就容易混乱. 所以, 我个人的想法是, 小版本号达到10次, 直接提升大版本号了, 不要再在小版本号上纠结了, 那些很细微的提升, 完全可以放到build编号中去.
对于只有简单的10次小版本升级大版本, 我们的版本号数值化, 直接使用:
let versionString = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
let version = Float(versionString)!
很简单的方式就能获得版本号, 然后可以用于比较等等.
如果必须要使用大于10次版本号的需要数值化, 则参考如下代码:
let maxVersionNum = 100 //假设小版本号最多只能升到100
let versionString = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
let version = versionString.components(separatedBy:".").reduce(0){ $0* maxVersionNum + Int($1)! }
相对复杂一点, 但是, 也就是一句代码的差别.
总之, 版本号的事, 本身就是一种弱规则, 每个公司, 完全可以根据自己的实际需求来. 但是, 如果你没有规则定义或者规则很乱的话, 可以参考这个设计.