App版本更新接口的设计

 

前段时间公司业务调整,新开了新的移动端的项目,所以和朋友聊到了“版本号”和“版本更新所需的数据表设计”。

一般来讲大部分的软件版本号分3段,比如 A.B.C

A 表示大版本号,一般当软件整体重写,或出现不向后兼容的改变时,增加A,A为零时表示软件还在开发阶段。 
B 表示功能更新,出现新功能时增加B 
C 表示小修改,如修复bug,只要有修改就增加C 

除了版本号之外还会有一些修饰的词,比如: 
alpha: 内部版本 
beta: 测试版 
rc: 即将作为正式版发布 
lts: 长期维护 

但老实讲,知名的项目没有几个是遵守上述规则的。 
商业软件完全取决于老板的意思,有时候还会配合宣传任意地来更改版本号。 
而历史悠久的开源项目,往往会有自己的规则,例如Linux用奇数版本表示开发板,偶数版本表示正式版等等。 

随着 Github 的出现,越来越多的人可以参与到贡献开源代码的活动中,版本号规则越来越混乱。 

Github 起草了一个具有指导意义的,统一的版本号表示规则,称为 Semantic Versioning(语义化版本表示). 该规则规定了版本号如何表示,如何增加,如何进行比较,不同的版本号意味着什么。

除此之外,作为产品,日常工作涉及版本更新,更是家常便饭,尤其是安卓产品,面对碎片化的渠道,总有些蛋蛋的忧桑,所以一张可扩展的数据表显得尤为重要。

起初我也有些凌乱,后来找朋友问了一下,具体如下:

checkversion | CREATE TABLE `checkversion` (

`id` int(11) NOT NULL,

`app_id` varchar(5) NOT NULL,  //各产品APP_ID

`app_name` varchar(20) NOT NULL, //各产品APP_名称  

`client_version` varchar(20) NOT NULL, //客户端版本号

`client_useragent` varchar(500) NOT NULL, //各渠道版本 ,以逗号分隔,可升级多渠道,全渠道用all,主要是区分多渠道的不同升级,比如腾讯某个渠道,并不让你升级到最新版本,则就可以不加上腾讯渠道。

`client_useragent_name` varchar(100) DEFAULT NULL, //渠道名称(防止泄露一般不填写)

 `download_url` varchar(100) NOT NULL, //升级下载网址 

 `update_id` int(11) NOT NULL DEFAULT '0', //关键是这个字段,记录本次版本应该升级到最新版本号,如本次为2,最新为3,则最新版本号的ID记录为15,则填15, 最新的记录则为0. 每一次APP升级请求API都会将低版本的记录自动更新为3

 `update_log` varchar(500) DEFAULT '', //升级日志

 `update_install` int(11) NOT NULL DEFAULT '0' COMMENT '是否强制安装', 

  PRIMARY KEY (`id`)

) ENGINE=MyISAM DEFAULT CHARSET=utf8   

再配上后台的自动或手动管理,就比较强大了,当然这个理解起来会有些别扭,但是使用起来却是任你升级变化万千,我都可以包容。

 

大家都知道,版本号一般由以下几部分组成:

1. 主版本号
2. 次版本号
3. 修正版本号
4. 编译版本号
例如:2.1.3 ,3.7.5,10.2.0
在比较版本号时,正确的做法应该是,主版本号和主版本号比较,次版本号和次版本号比较等等,也就是把版本号分割,对应的组成之间进行比较,如下:

/**
* 版本号比较
*
* @param version1
* @param version2
* @return
*/
public static int compareVersion(String version1, String version2) {
if (version1.equals(version2)) {
return 0;
}
String[] version1Array = version1.split("\\.");
String[] version2Array = version2.split("\\.");
Log.d("HomePageActivity", "version1Array=="+version1Array.length);
Log.d("HomePageActivity", "version2Array=="+version2Array.length);
int index = 0;
// 获取最小长度值
int minLen = Math.min(version1Array.length, version2Array.length);
int diff = 0;
// 循环判断每位的大小
Log.d("HomePageActivity", "verTag2=2222="+version1Array[index]);
while (index < minLen
&& (diff = Integer.parseInt(version1Array[index])
- Integer.parseInt(version2Array[index])) == 0) {
index++;
}
if (diff == 0) {
// 如果位数不一致,比较多余位数
for (int i = index; i < version1Array.length; i++) {
if (Integer.parseInt(version1Array[i]) > 0) {
return 1;
}
}

for (int i = index; i < version2Array.length; i++) {
if (Integer.parseInt(version2Array[i]) > 0) {
return -1;
}
}
return 0;
} else {
return diff > 0 ? 1 : -1;
}
}
结果说明:0代表相等,1代表version1大于version2,-1代表version1小于version2

通过此方法便可以直接进行android 版本号大小比较了,方法直接拿来用即可.
---------------------
作者:程大龙
来源:CSDN
原文:https://blog.csdn.net/qq_25749749/article/details/79847922
版权声明:本文为博主原创文章,转载请附上博文链接!

 

 

 

 

 

 

APP产品初期如何搭建简单有效的版本管理机制

APP产品初期,往往需要快速迭代,小步快跑。那也就意味着不会有过多的时间进行详细的APP版本规划。在该背景下,产品经理该如何搭建简单有效的版本管理机制?

▎前言.APP版本管理结构

我们不追求非常严密的流程制度,那样并不适合初创项目的节奏规律。对于初创项目,我们采取小步快跑的策略,将业务搭起来并顺利跑通,是我们的首要目标!所以接下来我们讨论的是如何搭建APP版本管理的"骨架"~

 
 

▎1.应用市场账号及物料准备

1.1应用市场账号

开发的APP最终是需要通过应用市场去推广的,如Android的华为应用市场、iOS的APP Store。所以第一步,选择应用市场;第二步,注册开发者账号。

选择应用市场

不需要覆盖所有的应用市场,只需要覆盖主流的应用市场即可。

 
 

注册开发者账号

我们登录各大应用市场的开发者网址后,申请企业开发者账号,所需要的物料除了《营业执照》公司的邮箱以外,其余的统统都根据注册流程按部就班的填写即可。当然,记住使用Excel备份:

 
 

1.2物料准备

物料准备就是实打实的体力活,但是这个体力活要做好不容易,比如到底需要准备什么物料,这些物料的规格要求又是怎么样的,如何去落实和管理。我特意为大家整理了一份完整版物料表格,以该表格作为一份CheckList,事半功倍~

 
 

▎2."蓝湖"设计协助平台搭建

一个APP必然会由众多的页面组成,也必然会有众多的参与者,包括产品狗、设计屎、还有后来者。万物多则乱之,而后乱则管之。我们借用"蓝湖"产品设计在线协助平台来管理我们的页面,并邀请不同模块负责的团队成员维护自己的页面,给出简单的交互与标注。

 
 

▎3.第三方数据服务接入/统计

数据分析是任何产品绕不开的一环,而目前市面上提供数据服务的供应商也比较成熟,可以选择一家主流的,让开发小哥哥接入其数据服务的SDK即可。如我目前所使用的第三方talkingData,通过其实现数据收集及基本的数据分析(累计用户、新增用户、版本使用分布、日活、留存等)。

 
 

▎4.APP迭代节奏制定

产品初期,往往需要快速迭代,小步快跑。所以我们制定的迭代周期是双周。通过快速的迭代周期,快速校验产品功能是否符合市场预期,或者功能优化是否有效。当然,迭代管理也是一门学问,涉及项目管理,我们不必过于深入。只要借助腾讯系的TAPD项目管理系统来协助我们完成即可。

 
 

▎5.应用市场提审策略

应用市场提审相当具有博弈性。

和谁博弈?和iOS应用市场的审核人员博弈(本质是和审核规则博弈);博弈什么?博弈能否过审上架APP Store;为什么要博弈?没办法,APP Store具有巨大的流量资源,同时其对上架的要求非常高,主要体现在[资质]上。

言归正传,什么场景下我们需要重点关注应用市场的提审策略?当我们的业务涉及以下敏感业务时,需要重点关注提审策略:

①非持牌金融机构提供的金融服务,例如P2P借款、导流给其它网贷平台。

②订阅、游戏内货币、游戏关卡、优质内容等虚拟充值类业务,例如Q币充值、爱奇艺会员。

③提供真实货币的游戏、彩票或竞猜活动,例如下注、扑克、一元购。

④涉及到假冒侵权的业务,例如A货、未授权的大牌销售。

如果涉及到上述的敏感业务,还想成功上架的话,那只有一招——巧妙的绕过去(骗审)。我们设计屏蔽逻辑,在审核期间与过审后采取不同的状态:

 
 

▎6.应用市场ASO管理

这是一个轻松的话题,什么是ASO,无非就是应用市场的排名优化,提高曝光。那我们要如何做?很简单,找人刷单。刷关键词、刷评论、刷下载量。反正,给钱,大爷~

 
 

▎7.版本过程资料管理

这个也简单,每个版本要把安装包、原型稿、设计稿、交互稿、需求范围列表等物料整理好,并在固定的文件夹保存好,作为公用资源即可。



作者:猩猩相嘻
链接:https://www.jianshu.com/p/a458c8c2e4ac
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

 

 

App版本更新接口的设计

 

 

Semantic Versioning 2.0.0

本文章翻译自 https://semver.org/
中文版在这里 https://semver.org/lang/zh-CN/,但读起来太困难。这里搞一版更教程化, 但又不失严谨的。

一个良好的版本号的结构与改动规则,向用户传达了我们软件中改动的影响级别。
作者在这篇官方文档里,给出了对 semver 的精准定义。

搬运正文

概述

给定一个版本号: MAJOR.MINOR.PATCH (主版本号.次版本号.补丁版本号):

  1. 当你修改了 API,使其(与之前版本)不兼容时,递增 MAJOR,
  2. 当你用向后兼容的方式加了些功能时,递增 MINOR,
  3. 当你用向后兼容的方式解决了几个 Bug 时,递增 PATCH

预发布版本 附加的标签,以及与编译相关的额外信息,可以作为 MAJOR.MINOR.PATCH 这种格式的扩展,加到版本号的后面。

引言

在软件管理的世界里, 有个可怕的地方, 叫 "Dependency Hell"[1]. 你的系统规模增长的越大, 集成到系统里的软件包越多, 你就越有可能发现, 某天, 你已经深深的陷入了这种绝望之地.

在那些有很多依赖包的系统里, 发布新的软件包版本很快就会变成一个梦靥. 如果依赖要求太紧, 你可能会陷入 "版本锁定" [2]. 如果版本要求太松, 你又不可避免的遭受"版本滥交"[3]之痛. [4]. 而所谓的 "Dependency Hell", 就是当 "版本锁定" 和/或 "版本滥交" 阻止你简单, 安全的推动项目前行的时候, 你的处境.

作为这个问题的一个解决方案, 我提议一套简单的规则和要求, 以规定如何分配和增长版本号. 这些规定基于, 但不限于已经在各种闭源, 开源软件中广泛使用的普遍惯例. 要想这套理论奏效, 首先你得声明一个公开的 API. API 可能是由文档组成的, 也可能是直接使用代码实现的. 但不管怎样, 重要的是这个 API 是清晰和精确的. 一旦你确定了你的 API, 使用增加特定的版本号的方式, 来传达 API 的改动. 考虑一个 X.Y.Z (MAJOR.MINOR.PATCH) 的版本号格式: 那么, 不影响 API 的Bug修复: 递增补丁版本号Z; 向后兼容的 API 的添加或修改: 递增次版本号; 不向后兼容的 API 的修改: 递增主版本号.

这套理论我称作 "Semantic Versioning", 那些个版本号以及他们的改变传达着与 底层代码, 以及从一个版本到另一个版本改了什么 相关的含义.

Semantic Versioning 规范

  1. 使用 Semantic Versioning 的软件 必须 声明一个公共的 API. 这个 API 可能是定义在代码里的, 或者仅仅存在于文档里, 不论用什么方式实现, 它都必须精确而全面.

  2. 一个正常的版本号必须使用 X.Y.Z 的格式, 其中 X, Y, 和 Z 都是非负的整数, 并且 必须不能 包含前导零.
    X 是主版本号, Y 是次版本号, 而 Z 是补丁版本号. 每个元素都必须以数字的方式递增. 举例: 1.9.0 -> 1.10.0 -> 1.11.0.

  3. 一旦一个打了版本的包被发布出去了, 那个版本的内容就 不能 再修改了. 任何修改 必须 作为一个新的版本重新发布.

  4. 主版本为零 (0.y.z) 的版本, 是用作初始开发阶段的. 任何东西都可能在任意的时间被更改. 这时候我们不应该认为它的 API 是稳定的.

  5. 1.0.0 版本表明对外公开 API 的形成. 从此之后, 版本号的递增方式取决于这个公开的API, 以及它如何修订.

  6. 补丁版本号Z (x.y.Z | x > 0) . 如果只有向后兼容的bug修复被引入的化, 补丁版本号 Z 必须 递增. "Bug修复"是指一个修正错误行为的内部修改.

  7. 次版本号Y (x.Y.z | x > 0). 如果一个新的, 向后兼容的功能被引入到了公开 API 里, 次版本号 必须 递增. 如果公开 API 的任何功能被标记为 "已弃用的", 次版本号 必须 递增. 如果大量的新功能或改进被引入到私有代码里的时候, 次版本号 可以 递增. 次版本号的改变 可以 包含补丁级别的改动. 当递增了次版本号的时候, 补丁版本号 必须 清零.

  8. 主版本号X (X.y.z | X > 0). 如果任何的向后不兼容的改动被引入到了公开 API中, 主版本号 必须 递增. 它的递增 可以 包含次版本和补丁级的改动. 当主版本号递增时, 次版本号和补丁版本号 必须 清零.

  9. 一个预发布版本 可以 通过在补丁版本号后面追加一个短线, 以及一系列的用点分割的标识符 来描述. 标识符 必须 仅包含 ASCII 的 阿拉伯数字和短线 [0-9A-Za-z-]. 标识符 必须不 为空. 数字标识符 不能 包含前导零. 预发布版本比对应的正常版本的优先级要低. 预发布版本表明, 它不稳定, 并且可能不满足其对应的正常版本所预定的兼容性要求. 例子: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92.

  10. 编译时的附加信息, 可以 通过在补丁版本号后面追加一个加号, 以及一系列的用点分割的标识符 来描述. 标识符 必须 仅包含 ASCII 的 阿拉伯数字和短线 [0-9A-Za-z-]. 标识符 必须不 为空. 在比较版本优先级的时候, 编译附加信息 应该 被忽略. 因此, 两个只有编译附加信息不同的版本, 具有相同的优先级. 编译附加信息的举例: 1.0.0-alpha+001, 1.0.0+20130313144700, 1.0.0-beta+exp.sha.5114f85.

  11. 优先级是指在排序的时候怎样比较不同的版本. 计算优先级的时候, 必须 将版本号以 "主版本号", "次版本号", "补丁版本号", "预发布标识符" 的顺序拆分. 优先级取决于, 在从左至右依次比较这些个标识符的时候, 发现的第一个差别. "主版本号", "次版本号", "补丁版本号" 总是以数字的方式参加比较. 举例: 1.0.0 < 2.0.0 < 2.1.0 < 2.1.1.
    当"主版本号", "次版本号", "补丁版本号" 都相同的时候, 预发布版本比正常的版本优先级要低. 举例: 1.0.0-alpha < 1.0.0.
    如果两个预发布版本有相同的 "主版本号", "次版本号", "补丁版本号", 优先级就 必须 通过比较点分割的标识符来确定, 从左至右依次比较, 直到发现一个不同: 只有数字的标识符号以数值高低比较, 有字母或连接号时则逐字以 ASCII 的排序来比较. 数字的标识符号比非数字的标识符号优先级低. 若开头的标识符号都相同时, 字段比较多的预发布版本号优先层级高. 举例: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0.

为什么使用 Semantic Versioning ?

(我的这套理论) 并不是什么新的或者革命性的点子,实际上,很可能你已经做了些很接近这个的工作。但问题在于,仅仅是“接近”并不够。如果不遵守有点儿"官方"的协定,版本号对于管理依赖来说基本没什么用。通过给我上面的思想命名,并给予其清晰的定义,将你的意图传达给你的软件的用户就变得很简单了。一旦意图清晰明了,最终一个灵活的(但也不是过于灵活的)软件依赖要求就可以搞定了。
我们可以通过一个简单的例子,展示一下 Semantic Versioning 可以让 “Dependency Hell” 成为历史。考虑一个叫做 “消防车” 的版本库,他需要一个使用了 Semantically Version 的软件包 “梯子”。当 “消防车” 刚创建的时候,“梯子”在3.1.0 版本。因为“消防车”使用了 “梯子” 3.1.0 新引入的功能,你可以简单的指定,你的“消防车” 对“梯子”的依赖要求是:大于等于 3.1.0 ,但小于 4.0.0 。现在,梯子 "3.1.1" 和 "3.2.0" 好了,你可以把他们发布到你的软件包管理系统,并且你知道他们跟现有的、跟它有依赖关系的包是兼容的。
作为一个负责人的开发者,你当然想验证任何软件包升级都是正常的、跟你宣传的一样。但现实世界是一团乱麻,对此我们除了小心再小心之外没有更好的办法。你能做的,是让 “Semantic Versioning” 提供你一个合理的方法去发布、升级软件包,而不必去搞许多新版的依赖包,节省了你的时间,免去了许多麻烦。
如果所有这些听起来挺给力的,要开始使用 “Semantic Versioning” 的话,你只需要声明你正在这么搞,然后遵守这些规范就好了。把这个网站链接到你的 README 文档里,以便其他其他人也可以了解这些规则,并从中受益。

FAQ

  • 在初始开发阶段,怎么去处理 0.y.z 的版本号?
    一个简单的做法是, 使用 0.1.0 作为第一版初始开发版本号,然后为随后的发布包递增次版本号(minor version)
  • 我怎么知道什么时候发布 1.0.0 版?
    如果你的软件已经在生产环境了(已经上线了), 很可能已经 1.0.0 了。如果你做好了一个 从此用户可以信赖的、稳定的API版本,你应该发布1.0.0。如果你正为向后兼容的事情心烦,你应该早就 1.0.0 了。
  • 这东西难道不会阻挠快速开发、快速迭代吗?
    为零的主版本就是为了快速开发的。如果你每天都在改 API,你要么还在 0.y.z,要么在另外一个开发分支上,为下一个主版本做准备。
  • 如果,哪怕是微小的 API 的不兼容改动,主版本都要蹦,我岂不是很快就到 42.0.0 版了?
    这是个关于为开发负责,以及前瞻性的问题。在有许多代码依赖之的软件中,不应该轻率的做不兼容的改动。升级招致的代价可能是相当大的。不得不通过递增主版本号来发行不兼容的改版,意味着你将充分考虑改动所带来的影响,并且评估所涉及的 成本/收益 比。
  • 整理个 API 的文档太费事儿了!
    为供他人使用的软件编写适当的文件,是你作为一名专业的开发者应尽的职责。“管理项目复杂度” 是保持项目高效的非常重要的一部分,而如果没有人知道如何使用你的软件,或者不知道哪些函数可以放心的调用的话,就不好做。Semantic Versioning,以及对 良好定义的API 的坚持,可以让每个人、每件事情都顺利进行。
  • 要是我不小心把一个不向后兼容的改动当成一个次版本号发布了怎么办?
    一旦发现你破坏了 Semantic Versioning 规范,马上解决这个问题,然后发布一个新的次版本,以恢复向后兼容。即使在这种情况下,直接修改已经发行的版本也是不可接受的。如合适,在文档里写明这个有问题的版本,并将这个问题告知你的用户,以便用户知晓这个出问题的版本。
  • 如果我在没有更新API的前提下,更新了我自己(软件)的依赖,应该怎么做?
    由于没有影响到公共 API,这将被当做是兼容的。那些使用了跟你一样的依赖包的软件,应该也有自己的依赖要求,并且如果有冲突的话,他们的作者会注意到的。要判定改动是属于补丁级别还是次版级别,要看你更新依赖包是为了修复Bug,还是添加新功能。对于后者,我通常觉着会有额外的代码,这种情况下,显然是一个次版本号级别的递增。
  • 如果我变更了公共 API 但无意中未遵循版本号的改动怎么办呢?(意即在补丁级的发布中,误将重大且不兼容的改变加到了代码之中)
    自行做最佳的判断。如果改回 API 预期的行为将强烈的影响你的大量受众,那么可能最好再发一个主版本吧,即使这个修复仅仅被当做一个补丁版本。记住,Semantic Versioning 所做的就是,通过版本号的改动传达含义。若这些改变对你的使用者很重要,那就通过版本号来告知他们。
  • 我该如何处理即将弃用的功能?
    弃用现存的功能,是软件开发中正常的一部分,也通常是向前发展所必须的。当你弃用部份 API 时,你应该做两件事:(1)更新你的文档让使用者知道这个改变(2)发布一个新的、仍然包含这些已经弃用的API 的次版本。在你从新的主版本里完全移除这些已弃用的功能之前,至少要有一个次版本 仍然包含这些已经弃用的 API,这样使用者才能平滑地转移到新版 API。
  • Semantic Versioning 对于版本的字串长度是否有限制呢?
    没有,但自行判断。举例来说,一个包含255个字符的版本字符串很可能太过分了。并且,特定的系统对于字串长度可能会有他们自己的限制。

  1. "依赖地狱". 因为不好翻译, 就不译了.

  2. "version lock" (如果不为每一个依赖包都发布一个新版本, 就没办法升级某个软件包).

  3. "version promiscuity" (承担了与太多未来版本兼容的责任, 远远超过合理的需要).

  4. 依赖过紧举例: 假设软件 A 依赖软件 B, 声明 A 的当前版需要 B 的 v1.1 版本, A 的下一个版本需要 B 的 v1.2 版本. 这就过紧了. 这样如果要将A升级到下一个版本, 你就不得不同时发布 B 的 v1.2 版本; 依赖过松举例: 声明 A的当前版本需要B, 只要 B 的版本大于 v1.1 即可. 这样子A 负担过重了, 处理与太多的B的未来版本的兼容问题, 没什么必要.



作者:Shawn_xiaoyu
链接:https://www.jianshu.com/p/e2619a7aa60e
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

 

posted @ 2019-05-10 20:18  沧海一滴  阅读(3079)  评论(0编辑  收藏  举报