CodePush熱更新雲服務在Cordova專案中的應用實踐
前言
由於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)
官網:
今天我們主要來看一下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!
總結
整體來講, 這個熱更新的速度還是蠻快的,實踐效果也很不錯,而且是微軟維護,開源專案,服務還是很有保障的,如果專案需要可以嘗試一下!