什麼是CodePush(熱更新)?
簡單來說,CodePush就是一種讓開發者對已發布的APP進行即時代碼更新的工具,而不需要通過應用商店的傳統發版流程,有點類似網頁那樣即時更新。
在傳統的APP開發中,一旦產品開發完成並發布到Android或iOS的商店,任何後續的功能更新或修復都需要重新發布新版本,並依賴於用戶主動前往商店更新。對於需要快速迭代的產品,會比較低效,還可能使部分用戶長時間停留在舊版本。
source
CodePush 的運作原理
source
可以將CodePush想像成一個中央更新倉庫(CodePush Cloud)。當我們有新的更新時,可以直接推到這個倉庫上。隨後,當用戶打開APP時,APP會查詢是否有可用更新。一旦有更新,就會自動下載。
CodePush更新主要適用於 JavaScript 程式碼和靜態資源。當APP偵測到CodePush的有新更新,並成功下載後,舊的 JavaScript 程式碼和資源就會立即被更新,讓用戶可以立即體驗到新的功能或修復的問題,一切都不需要經過應用商店的審核或更新流程。要注意的是,若我們的更新涉及到原生模組的更改或需要更新原生依賴時,就不能使用CodePush,要走傳統發版更新。
CodePush方案
時下主流方案是Code Push、Pushy。
今天會介紹的是Code Push,這是微軟的 App Center 的其中一項服務,底層是基於 Azure。
全局安裝 App Center CLI
npm install -g appcenter-cli
登入並配置 App Center 帳號
appcenter login
執行以上命令後,系統會提示「Access code from browser」。此時,會自動開啟一個App Center的網頁。
選擇你的登入方式進行登錄。成功登入後,會看到一串token。複製這串token,然後貼上到之前的「Access code from browser」,按下Enter,即完成登入操作。
創建APP
進到https://appcenter.ms/ ,按add new app創建APP
或是使用命令
appcenter apps create -d <AppName> -o Android -p React-Native
appcenter apps create -d <AppName> -o iOS -p React-Native
部署Staging和Production環境和key
appcenter codepush deployment add -a <ownerName>/<appName> Staging
appcenter codepush deployment add -a <ownerName>/<appName> Production
部署完畢後,可以用以下指令查看對應的key
appcenter codepush deployment list -k -a <ownerName>/<appName>
安裝
npm install --save react-native-code-push
cd ios && pod install
在AppDelegate.m
,增加引入
#import <CodePush/CodePush.h>
找到
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
修改為
return [CodePush bundleURL];
整合key進專案
在Info.plist
新增一個CodePushDeploymentKey,string中放入key
<key>CodePushDeploymentKey</key>
<string>your key</string>
不知道key的話,可以用以下指令查
appcenter codepush deployment list --app <ownerName>/<appName> -k
在android/settings.gradle
,新增:
include ':app', ':react-native-code-push'
project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')
在android/app/build.gradle
,新增:
apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"
修改MainApplication.java
import com.microsoft.codepush.react.CodePush;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
...
// 2. Override the getJSBundleFile method to let
// the CodePush runtime determine where to get the JS
// bundle location from on each app start
@Override
protected String getJSBundleFile() {
return CodePush.getJSBundleFile();
}
};
}
將key放到strings.xml
<resources>
<string name="app_name">AppName</string>
<string moduleConfig="true" name="CodePushDeploymentKey">DeploymentKey</string>
</resources>
CodePush.sync()
這是CodePush的主要方法,它會檢查伺服器上是否有可用的更新,並根據提供的選項進行下載和安裝。
installMode: 決定下載後如何安裝更新。
IMMEDIATE
: 馬上安裝更新。ON_NEXT_RESTART
: 在下次應用重新啟動時進行更新。ON_NEXT_RESUME
: 如果應用已經在後臺超過了指定的時間,那麼當它恢復時,更新會被應用。checkFrequency: 決定應用何時檢查更新。
ON_APP_START
: 每次應用啟動時檢查更新。ON_APP_RESUME
: 每次應用從後臺返回前臺時都會檢查。MANUAL
: 需要手動呼叫CodePush.checkForUpdate()
進行檢查。CodePush.SyncStatus
當呼叫CodePush.sync()時,它將會回傳當前的同步狀態。以下是一些常見的狀態:
UP_TO_DATE
: 應用程式已經是最新的,沒有可用的更新。UPDATE_INSTALLED
: 更新已經被下載且已安裝到裝置中。CodePush.CheckFrequency
用於確定CodePush.sync()應該多頻繁的檢查更新。
ON_APP_START
: 每次應用啟動時。ON_APP_RESUME
: 每次應用從後臺返回前臺時。MANUAL
: 僅當手動呼叫CodePush.checkForUpdate()
時。引入CodePush
import CodePush from 'react-native-code-push';
檢查CodePush更新
import React, { useEffect } from 'react';
import { View, Text, Button, Alert } from 'react-native';
import CodePush from 'react-native-code-push';
const App = () => {
useEffect(() => {
checkForUpdate();
}, []);
const checkForUpdate = () => {
CodePush.sync({
installMode: CodePush.InstallMode.IMMEDIATE,
},
(status) => {
switch (status) {
case CodePush.SyncStatus.UP_TO_DATE:
Alert.alert("提醒", "當前已經是最新版本");
break;
case CodePush.SyncStatus.UPDATE_INSTALLED:
Alert.alert("提醒", "最新版本已安裝");
break;
default:
break;
}
});
};
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>CodePush 範例</Text>
<Button title="檢查更新" onPress={checkForUpdate} />
</View>
);
};
export default CodePush({
checkFrequency: CodePush.CheckFrequency.ON_APP_START,
})(App);
使用以下命令在專案的root資料夾下發布更新
# 測試環境
appcenter codepush release-react -a <ownerName>/<appName> -d Staging
# 正式環境
appcenter codepush release-react -a <ownerName>/<appName> -d Production
發布完畢後,可以用以下命令查詢CodePush歷史
appcenter codepush deployment history -a <username>/<appName> Staging
Install Metrics表示更新被多少用戶裝置安裝。
Description、Mandatory、App Version,這幾個是我們在發布時的可選項
另外target-binary-version版本指的是原生的版本號,有些新手可能不太熟,順便說明一下查看原生版本號的方法:
加上以上三個選項的發布範例:
appcenter codepush release-react -a <ownerName>/<appName> -d Staging -desc "修復了登錄問題" -m -t 1.2
https://learn.microsoft.com/zh-tw/appcenter/distribution/codepush/rn-get-started