前言
由於App每次升級打包的繁瑣性,項目中不想進行二次打包,這就需要實時更新的服務,探索了許久,發現CodePush滿足了我們的需求。
CodePush 是微軟開發的,可以實時更新 React Native 和 Cordova 應用。
CodePush 是提供給 React Native 和 Cordova 開發者直接部署移動應用更新給用戶設備的雲服務。
CodePush 作爲一個雲倉庫,作爲開發者可以直接推送更新到 JS, HTML, CSS and images,應用可以從客戶端 SDKs 裏面查詢更新。
CodePush 可以讓我們在修復一些小問題和添加新特性的時候,不需要經過二進制打包,可以直接推送代碼進行實時更新。
CodePush 可以進行實時的推送代碼更新:
- 直接對用戶部署代碼更新 管理 Alpha,Beta 和生產環境應用
- 支持 Cordova 和 React Native
- CodePush提供兩個客戶端 SDKs(Cordova 和React Native)
官網:
http://microsoft.github.io/code-push/index.html#getting_started
今天我們主要來看一下CodePush在Cordova項目中是如何應用的:
Cordova中的應用
大概步驟如下,僅供參考:
安裝CodePush CLI
sudo npm install -g code-push-cli
創建一個CodePush的雲賬戶
code-push register
當執行這個命令,會自動打開瀏覽器,讓你選擇是github驗證還是微軟賬戶驗證,這裏我們通常選擇github:
點選認證完畢會給我們一個key,在把這個key粘貼到命令行中:
回車後創建完成。
在雲服務中註冊我們的App
code-push app add <appName>
例如:
code-push app add MyDemo
註冊完成後,我們會看到下面截圖:
這裏會有兩個deployment key, 我們有時候需要建兩個項目針對不同平臺,比如React-native的js bundle是不同的,所以需要分開配置, Cordova同樣的道理,沒有特殊需求,我們也可以使用一個key.
創建一個cordova項目
創建項目
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 *" />
編寫JS檢查更新代碼
通常來講,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!
總結
整體來講, 這個熱更新的速度還是蠻快的,實踐效果也很不錯,而且是微軟維護,開源項目,服務還是很有保障的,如果項目需要可以嘗試一下!