用户无需到App Store更新就能用到新的代码,原理说出来也简单,就是在APP打开的时候,调用SOT的API,通过网络同步到SOT的补丁,并且加载该补丁。加载补丁后,就会用新的代码替换掉原来APP的代码,实现无感知的更新。本文介绍同步补丁的API接口如何使用,开发者根据自己的需要来做出选择。
1.05版本之后的SotWebService.h里,有三个网站版的接口API,分别是Sync,ApplyCachedAndPullShip,PullShip。其中Sync和ApplyCachedAndPullShip选择其一即可,PullShip可以和ApplyCachedAndPullShip配合着用。
调用它们需要的参数都是一样的,分别是:
下面分别介绍每个接口的使用场景和方式。
Sync是最简单的接口,每次调用时,会去同步最新的补丁,同步成功时就会直接加载该补丁,成功的回调结果是SotScriptStatusSuccess。
但假如手机没有网络,则无法同步到补丁信息。所以也不会加载任何补丁(即使之前有网络的时候,手机已经成功同步过补丁),回调会返回错误。
注意该接口去网站上拉取补丁,是有网络延迟的,所以该接口是个异步回调接口,只有回调SotScriptStatusSuccess之后,APP才开始用补丁的代码。所以通常首屏代码用该接口无法热更,因为在补丁还没有传输到手机上时,首屏代码都已经被调用了,那必然还是老的代码。所以请使用者注意调用时序的问题,下面是一个调用API的例子:
调用的时序如下图:
该接口可以在APP打开期间调用多次,每次都会同步最新的补丁状态,并且重新加载当前最新的补丁。例如APP一直在后台没有被杀死,当被唤醒到前台时,代码里有写进行一次Sync同步,就会同步和加载最新的补丁。虽然可以这么做,但我不建议,因为可能会引起一些奇怪的BUG,例如旧补丁新增了一些函数,而在新补丁中删掉了。
假如APP已经加载过了补丁,此时开发者在网站后台禁用所有补丁,假如APP没有被杀死,又进行了一次Sync同步,那么也不会把之前加载过的补丁卸载,只有完全退出并且重启APP,才不会去加载任何补丁。
上面介绍的Sync接口,使用起来比较简单,但是有两个缺点。一是没有网络的情况下无法使用,即使之前已经同步过了补丁。二是需要考虑网络延迟,导致一些调用时机比较早的代码,无法被替换,例如首屏初始化代码。
ApplyCachedAndPullShip接口可以解决上面的问题。调用该接口时,会直接加载上一次同步成功的补丁,因为上一次成功同步的补丁,已经被缓存到了本地。加载补丁的同时也会向网站发起一次补丁同步,并在回调中告知调用方,本地缓存的补丁是否还是最新的,通常会有以下三种结果:
下面是一个调用的例子:
代码:
SotApplyCachedResult ApplyShipResult = [SotWebService ApplyCachedAndPullShip:@"1234567" is_dev:false cb:^(SotDownloadScriptStatus status) { if(status == SotScriptShipAlreadyNewest) { NSLog(@"SyncOnly SotScriptShipAlreadyNewest"); } else if(status == SotScriptShipHasSyncNewer) { NSLog(@"SyncOnly SotScriptShipHasSyncNewer"); } else if(status == SotScriptShipDisable) { NSLog(@"SyncOnly SotScriptShipDisable"); } else { NSLog(@"SyncOnly SotScriptStatusFailure"); } }]; if(ApplyShipResult.Success) { if(ApplyShipResult.ShipMD5) NSLog(@"sot success apply cached ship md5:%@", ApplyShipResult.ShipMD5); }当成功加载本地缓存的补丁时,则会马上替换掉老代码,所以只要在首屏代码调用前,调用该接口,则可以实现热更新首屏代码。
调用的时序如下图:
接口也可以被调用多次,每次调用也会卸载旧补丁并且加载新的缓存好的补丁,但不建议如此操作。
这个接口也并非完美,因为本次打开APP时使用的是之前缓存下来的补丁,所以可能不是最新的,新补丁需要推迟到下一次启动才能加载。
为了让APP更快地同步到最新的补丁,提供了PullShip接口,该接口只会去网站上同步当前补丁状态,发现新补丁则会缓存下来,供下次启动时使用。
接口的调用方式和结果的意义和ApplyCachedAndPullShip接口是完全相同的。这两个接口很像,PullShip只是同步而不加载,ApplyCachedAndPullShip即加载也同步。
这三个接口每次调用,都会发起一次补丁同步,消耗1瓦力。如果同步失败,例如网络有问题或者别的错误发生,则会自动重试一次。同步的请求因为网络原因而没有发送到网站,则不会被统计到,所以也不会消耗瓦力。
所有接口同步时,如果发现有更新的补丁时,需要消耗下载费用,补丁每100KB消耗3瓦力。之后都会把补丁文件缓存到本地,缓存过后下次同步,不会再消耗下载补丁的费用。