对于RN开发而言,最方便的就是热修复了,我们公司项目集成的热修复是:react-native-update,但是我们的用户主要针对尼日利亚用户,而国内的react-native-update补丁包是放在国内七牛上的,因此访问巨慢,加上尼日利亚那边基本都是3G,综合考虑该换微软的:CodePush.
对于CodePush而言,东西是真的多,覆盖问题真的全,因此我们需要摘出我们需要的东西——根据需求找需要。
需求:
综上所需: 我们得出两点:
进入正题,首先是安装CodePush脚手架:
npm install -g appcenter-cli
然后安装CodePush :
npm install --save react-native-code-push
接着就是配置Android和IOS环境:
Android IOS配置链接
配置成功之后,我们需要先在项目根目录登录codePush:
appcenter login
登录成功之后会显示owner-name 需要记一下。
创建应用(Android):
appcenter apps create -d TestCodePush -o Android -p React-Native
其中TestCodePush 是你自己的项目名。
然后创建分支:开发分支,还有线上分支,当然了你也可以创建测试分支以及灰度分支:
appcenter codepush deployment add -a / Staging
appcenter codepush deployment add -a / Production
上述命令行,创建成功之后都会显示一个key, 这个key就是配置Android项目中的key。
当然了可以运行
appcenter codepush deployment list -a / --displayKeys
查看key。
至此,我们的环境就算基本搭建完成了。
在此我想说个问题就是:按照官网的说啊,需要发不到Google市场,这个一直挺困扰我的,刚开始我的配置出了问题,让我误以为是没有发布到Google市场的缘故。在此我想说的是:你不发布到Google市场也是可以的。官网说的发不到google市场是因为:在老外的眼里,你不发布到Google市场,用户怎么下载你的app呢?
好,现在在分析一遍我们的需求:
**
此时客户端和服务端比对version,如果客户端的version小于服务端的version,说明这是我们已经发布了新版本,此时需要检测看看是大更新还是小更新。
**
**
此时需要检测是否是大版本还是小版本更新:
import codePush from "react-native-code-push";
codePush.checkForUpdate()
.then((update) => {
if (!update) {
console.log("The app is up to date!");
} else {
console.log("An update is available! Should we download it?");
console.log("更新:" + JSON.stringify(update));
console.log("----" + JSON.parse(update.description));
codePush.sync(
{updateDialog: false, installMode: codePush.InstallMode.ON_NEXT_RESUME},
this.codePushStatusDidChange.bind(this),
this.codePushDownloadDidProgress.bind(this)
);
}
});
此时我们需要从update取出数据,
从上述JSON可以看出我们可以从description取出我们想要的数据。 至于怎么设置该字段,后面再说。
**
**
我们可以从Update对象中获取,一个字段是:是否是大更新。如果是:跳转Google市场。
如果是小更新,那么下一步:
**
**
跟上步骤一样,可以在description的JSON中添加一个字段:是否需要强制更新。
**
**
此时不管是否是强制的,都需要下载热补丁包,codepush提供了下载,安装以及获取下载进度为一体的函数:codePush.sync()
codePush.sync(
{updateDialog: false, installMode: codePush.InstallMode.ON_NEXT_RESUME},
this.codePushStatusDidChange.bind(this),
this.codePushDownloadDidProgress.bind(this)
);
首先我们需要设置updateDialog为false,因为如果有下载弹窗,那么我们肯定要自定义啊,比如我们的是一个:大火箭弹窗=-=,炫的一笔。
至于安装模式:InstallMode.ON_NEXT_RESUME, 官网是这样定义的:
codePush.InstallMode.ON_NEXT_RESUME (2) - 表示您要安装更新,但不希望重新启动应用程序,直到最后一个用户从后台恢复它。这样,您不会中断当前会话,但是您可以更快地在它们前面获得更新,然后必须等待下一次自然重启。此值适用于可以以非侵入方式在恢复时应用的静默安装。
codePushStatusDidChange方法是获取下载,安装或者失败状态的:
codePushStatusDidChange(syncStatus) {
// if (this.state.immediateUpdate) {
switch(syncStatus) {
case codePush.SyncStatus.CHECKING_FOR_UPDATE:
console.log('::: Checking for update');
this.syncMessage = 'Checking for update'
break;
case codePush.SyncStatus.DOWNLOADING_PACKAGE:
console.log('::: Downloading package');
this.syncMessage = 'Downloading package'
break;
case codePush.SyncStatus.AWAITING_USER_ACTION:
console.log('::: Awaiting user action');
this.syncMessage = 'Awaiting user action'
break;
case codePush.SyncStatus.INSTALLING_UPDATE:
console.log('::: Installing update');
this.syncMessage = 'Installing update'
break;
case codePush.SyncStatus.UP_TO_DATE:
console.log('::: App up to date.');
this.syncMessage = 'App up to date.'
break;
case codePush.SyncStatus.UPDATE_IGNORED:
console.log('::: Update cancelled by user');
this.syncMessage = 'Update cancelled by user'
break;
case codePush.SyncStatus.UPDATE_INSTALLED:
console.log('::: Update installed and will be applied on restart.');
this.syncMessage = 'Update installed and will be applied on restart.'
codePush.restartApp(true);
break;
case codePush.SyncStatus.UNKNOWN_ERROR:
console.log('::: An unknown error occurred');
this.syncMessage = 'An unknown error occurred'
break;
}
// }
}
注意:当状态为:codePush.SyncStatus.UPDATE_INSTALLED的时候,说明已经下载完成了,此时就等你是现在重启还是下次启动释放补丁包。此时就是区别是否是强制更新。如果是强制更新,讲道理肯定是需要立即重启的:codePush.restartApp(true); 如果不是强制的,那么就不调用restartApp方法。
获取进度信息:
codePushDownloadDidProgress(progress) {
console.log("--------::: " + JSON.stringify(progress));
}
progress对象包含:已下载进度以及总大小。
最后注意:需要在我们的根目录用codePush包裹:
import codePush from "react-native-code-push";
let codePushOptions = {
checkFrequency : codePush.CheckFrequency.MANUAL
}
export default codePush(codePushOptions)(App);
至于我们为什么设置为:MANUAL, 需求:我们自己控制是否检测更新,官网:
codePush.CheckFrequency.MANUAL (2) - 禁用自动检查更新,但仅检查codePush.sync()应用程序代码中何时调用。
至此我们的代码流程完了,此时就是我们发布更新,对于发布更新我们,可以执行以下命令:
appcenter codepush release-react -a 235434504-qq.com/TestCodePush -d Staging -m true --description [{\"content\":\"aaaa\"},{\"content\":\"bbbbbbc\"}] -t 1.0.1
235434504-qq.com : 你自己的owernName。
TestCodePush : 你自己的项目名称
Staging : 发布分支。
-m : 是否是强制更新, 在此我定义为(是否是大版本更新!)
–description: 在此自定义输入JSON字符串
-t: 我们APP打包的真正的version,如果Android版本:也就是我们的versionName.
**
**
对于国内的热修复方案,使用的话挺简单的,考虑的方面可能没有微软的codePush周全,但是推出react-native-update,个人感觉真的挺厉害的,毕竟别人整出来了,有本事你上啊? 哈哈。
在此我想说一下react-native-update的使用新得吧