iOS 上的版本策略

前言

不少 iOS 应用都有一套版本策略,来做控制.而现在为应对各大市场的审核,安卓也都开始需要根据版本来做一些控制。

一般做版本控制目的不外乎这几点:

  • 上线前:审核前后的逻辑控制
  • 上线后:提示更新/强制更新
  • 下架:兜底引导

审核需求

对于过审核来说,客户端需要的信息,最基本的一项是:

  • 当前商店版本

因为对客户端来说,自身版本是已知的.

通过和当前商店版本的比对,能知道客户端当前属于是审核状态,还是过审状态

1
2
3
4
5
if(客户端版本>商店版本){
//审核时逻辑
}else{
//过审核逻辑
}

这样只要等待我们的应用通过审核后,让服务端更新当前商店版本,就可以发布出去了.

note: 需要注意的是,为防止网络不好的情况,在得不到网络数据回来之前,默认状态要是 “审核模式”,避免展露出敏感信息。

过审刷新

网络的状态是复杂,因此请求存在长短不一的网络延时

例如首页的 UI 在审核时是 A 样式,过审后是 B 样式。

在上线后,请求没有很快的响应,用户进入默认的审核模式,看到是 A 样式。

那么请求回来后,得到版本信息,要及时刷新成 B 样式,避免用户一直在审核模式当中。

要通过回调,在各处关键点的地方做刷新处理。

标记线上用户

进一步追求更好的体验,最好不展示审核模式 给到普通用户,那么可以尝试对用户进行标记。

目前想到是,根据自己应用特征,来做标记,能够用到这个行为的,那一定是你的普通用户。

1
2
3
if(doSomeThing){
普通用户=YES;
}

那么通过用户标记,在之后的更新中,可以减少审核判断和刷新

1
2
3
4
if(普通用户==YES){
return;
}
//审核模式

引导升级

提示更新

客户端已经知道当前商店版本,那么有一件可以顺带在一起干的事情–提示更新。

由于 iOS 的规定,我们不能让用户在 APP 上直接更新应用。

但在有新版本的时候,我们都希望用户可以尽快更新体验上新功能。

所以在过审核之后,可以通知到低版本用户,商店已经有新版本。

1
2
3
if(客户端版本<商店版本){
//提示更新
}

而有的版本,可能不需要提示,所以再加上一个更新提示开关:

1
2
3
4
5
6
if(更新提示开关==NO){
return;
}
if(客户端版本<商店版本){
//提示更新
}

如果提示更新每次打开都触发,有些频繁,所以可根据时间设定频率,隔一段时间内,客户端再提示一次。

这里逻辑就又复杂一些:

1
2
3
4
5
6
7
8
9
10
11
if(更新提示开关==NO){
return;
}
间隔时间 = 现在时间-提示时间;
if(间隔时间<规则间隔){
return ;
}
if(客户端版本<商店版本){
提示时间 = 现在时间
//提示更新
}

服务端区分版本请求

而经过实践,实际情况看起来更复杂一点。

苹果的上架后,用户是逐步更新的,所以直接开启提示更新,那么有的用户在 App 内收到提示更新 ,结果点击去到商店,版本却没有更新。

解决方法就是:服务端需要为此,根据客户端版本,来返回不同的值。

例如商店版本为 1.3 时,可以分情况处理:

客户端 服务器返回结果
审核 1.4 1.3
刚过审核 1.3 1.3
其它 1.0/1.1/1.2 1.2

对于不同版本的客户端请求,做额外处理,避免用户收到提示后,却更新不到的问题。

等过一段时间稳定后,再做提示。

强制更新

前面说到提示更新,而对于某些情况,我们希望用户必须升级

比如出了重大Bug,在核心路径上不可用,那么我们希望用户直接升级到新版本,或者非常重要的功能升级,例如 1.0 到 2.0 的情况。

对于需要强制更新的情况,我们可以再做一个强制更新开关

1
2
3
4
5
6
7
if(客户端版本>=商店版本){  
return;
}
if(强制更新开关==YES){
//强制更新
return;
}

而有时候,我们不是希望所有版本都做强制更新。

例如,最新版本是 2.0,我们希望 1.7.0 以下的用户强制更新,对于较新的 1.8/1.9 用户,不需要强制更新。

那么,还需要一个强制版本作为参照

1
2
3
4
5
6
7
8
9
if(客户端版本>=商店版本){  
return;
}
if(强制更新开关==NO){
return;
}
if(客户端版本<=强制版本){
//强制更新
}

兜底引导

拥有了上面几个功能之后,基础的版本策略已经完成了。

由于审核政策的变幻莫测,说不定就遭遇拒审,无法上架等尴尬的境地。

防患于未燃,我们最后再加入一个关键的功能,兜底引导。

这时我们还需要一个兜底引导配置,引导用户跳转我们的新应用或者新地址当中,来争取最后一线的生机。

如果需要细化功能,可以放在服务配置里,做额外参数来展示。

我们目前是配置一个 url 来做打开动作

1
2
3
4
url = newUrl;
if([url isNotBlank]){
[router openurl:url];
}

总结

目前这一套策略,也经过了实践,渐渐进化而来。

覆盖从上线前的过审,上线时的更新,下架时兜底的版本策略。

如果有疏漏,或者考虑不够的地方,欢迎大家一起指教补充和讨论 : )