由于App每次升级打包的繁琐性,项目中不想进行二次打包,这就需要实时更新的服务,探索了许久,发现CodePush满足了我们的需求。
CodePush 是微软开发的,可以实时更新 React Native 和 Cordova 应用。
CodePush 是提供给 React Native 和 Cordova 开发者直接部署移动应用更新给用户设备的云服务。
CodePush 作为一个云仓库,作为开发者可以直接推送更新到 JS, HTML, CSS and images,应用可以从客户端 SDKs 里面查询更新。
CodePush 可以让我们在修复一些小问题和添加新特性的时候,不需要经过二进制打包,可以直接推送代码进行实时更新。
CodePush 可以进行实时的推送代码更新:
官网:
http://microsoft.github.io/code-push/index.html#getting_started
今天我们主要来看一下CodePush在Cordova项目中是如何应用的:
大概步骤如下,仅供参考:
sudo npm install -g code-push-cli
code-push register
当执行这个命令,会自动打开浏览器,让你选择是github验证还是微软账户验证,这里我们通常选择github:
点选认证完毕会给我们一个key,在把这个key粘贴到命令行中:
回车后创建完成。
code-push app add
例如:
code-push app add MyDemo
注册完成后,我们会看到下面截图:
这里会有两个deployment key, 我们有时候需要建两个项目针对不同平台,比如React-native的js bundle是不同的,所以需要分开配置, Cordova同样的道理,没有特殊需求,我们也可以使用一个key.
创建项目
cordova create MyDemo com.delawareconsulting.pushDemo MyDemo
添加平台
cd MyDemo
cordova platform add android
cordova platform add ios
添加插件
cordova plugin add cordova-plugin-code-push@latest
cordova plugin add cordova-plugin-whitelist
配置deployment keys:
<platform name="android">
<preference name="CodePushDeploymentKey" value="YOUR-ANDROID-DEPLOYMENT-KEY" />
platform>
<platform name="ios">
<preference name="CodePushDeploymentKey" value="YOUR-IOS-DEPLOYMENT-KEY" />
platform>
也可以用命令配置:
code-push deployment ls APP_NAME -k
config.xml中配置访问权限:
<access origin="https://codepush.azurewebsites.net" />
<access origin="https://codepush.blob.core.windows.net" />
<access origin="https://codepushupdates.azureedge.net />
index.html配置白名单安全协议:
<meta http-equiv="Content-Security-Policy" content="default-src https://codepush.azurewebsites.net 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *" />
通常来讲,app检查更新会发生在启动后,或者setting 页面的检查更新按钮,再或者发生在从后台返回app的时候。
执行检查更新:
window.codePush.checkForUpdate(app.checkSuccess, app.getErrorHandler("Checking for update failed."));
检查成功已有更新:
checkSuccess: function (remotePackage) {
if (!remotePackage) {
// A null remotePackage means that the server successfully responded, but there is no update available.
console.log("The application is up to date.");
}
else {
console.log("There is an update available. Remote package:" + JSON.stringify(remotePackage));
// Called after the user confirmed or canceled the update
function onConfirm(buttonIndex) {
switch (buttonIndex) {
case 1:
/* Install */
console.log("Downloading package...");
remotePackage.download(app.onDownloadSuccess, app.getErrorHandler("Downloading the update package failed."));
break;
case 2:
/* Cancel */
/* nothing to do */
break;
}
}
// Ask the user if they want to download and install the update
navigator.notification.confirm(
'An update is available. Would you like to download and install it?',
onConfirm,
'Update'
['Install', 'Cancel']);
}
},
执行下载成功操作:
// Called after an update package was downloaded sucessfully.
onDownloadSuccess: function (localPackage) {
console.log("Local package downloaded. Local package: " + localPackage.localPath);
var installCallback = function () {
console.log("Install succeeded");
};
console.log("Installing package...");
localPackage.install(installCallback, app.getErrorHandler("Installation failed."), { installMode: InstallMode.IMMEDIATE });
},
还有另外一种检查方式:
// Download the update silently, but install it on
// the next resume, as long as at least 5 minutes
// has passed since the app was put into the background.
codePush.sync(null, { installMode: InstallMode.ON_NEXT_RESUME, minimumBackgroundDuration: 60 * 5 });
// Download the update silently, and install optional updates
// on the next restart, but install mandatory updates on the next resume.
codePush.sync(null, { mandatoryInstallMode: InstallMode.ON_NEXT_RESUME });
// Changing the title displayed in the
// confirmation dialog of an "active" update
codePush.sync(null, { updateDialog: { title: "An update is available!" } });
// Displaying an update prompt which includes the
// description associated with the CodePush release
codePush.sync(null, {
updateDialog: {
appendReleaseDescription: true,
descriptionPrefix: "\n\nChange log:\n"
},
installMode: InstallMode.IMMEDIATE
});
发布更新过程中,我们可以针对不同平台进行发布,注意这个操作一定要在基于cordova的项目结构下,否则会报错的哦。
code-push release-cordova <appName> <platform>
code-push release-cordova MyApp-ios ios
code-push release-cordova MyApp-Android android
会看到如下截图,表示发布成功:
重启我们的app, 会提示有更新,点击下载后,即可看到最新的版本。
这里我们不用担心,发布更新时候,需要下载全部的文件,这个终端会自行处理,只现在改变的文件,所以我们大可放心。
查看发布状态:
code-push deployment list MyDemo
指定版本描述:
code-push release-cordova MyDemo ios -m --description "update default title"
查看当前账户的apps:
code-push app list
回滚到上一个版本操作:
code-push rollback MyApp Production|Staging
本人一直在寻找如何能够查询到创建app时候返回的deployment keys(Production, Staging), 但是一直没发现。
建议大家保存好这个key!
整体来讲, 这个热更新的速度还是蛮快的,实践效果也很不错,而且是微软维护,开源项目,服务还是很有保障的,如果项目需要可以尝试一下!