iT邦幫忙

2023 iThome 鐵人賽

DAY 27
0
Mobile Development

30天React Native之旅:從入門到活用系列 第 27

Day 27:CodePush - 實現React Native APP的即時更新

  • 分享至 

  • xImage
  •  

CodePush 介绍

  • 什麼是CodePush(熱更新)?
    簡單來說,CodePush就是一種讓開發者對已發布的APP進行即時代碼更新的工具,而不需要通過應用商店的傳統發版流程,有點類似網頁那樣即時更新。

    在傳統的APP開發中,一旦產品開發完成並發布到Android或iOS的商店,任何後續的功能更新或修復都需要重新發布新版本,並依賴於用戶主動前往商店更新。對於需要快速迭代的產品,會比較低效,還可能使部分用戶長時間停留在舊版本。
    https://ithelp.ithome.com.tw/upload/images/20231012/20103365SoK5YdSMck.png
    source

  • CodePush 的運作原理
    https://ithelp.ithome.com.tw/upload/images/20231012/20103365wFKd9ftoI8.png
    source

    可以將CodePush想像成一個中央更新倉庫(CodePush Cloud)。當我們有新的更新時,可以直接推到這個倉庫上。隨後,當用戶打開APP時,APP會查詢是否有可用更新。一旦有更新,就會自動下載。

    CodePush更新主要適用於 JavaScript 程式碼和靜態資源。當APP偵測到CodePush的有新更新,並成功下載後,舊的 JavaScript 程式碼和資源就會立即被更新,讓用戶可以立即體驗到新的功能或修復的問題,一切都不需要經過應用商店的審核或更新流程。要注意的是,若我們的更新涉及到原生模組的更改或需要更新原生依賴時,就不能使用CodePush,要走傳統發版更新。

  • CodePush方案
    時下主流方案是Code Push、Pushy。
    今天會介紹的是Code Push,這是微軟的 App Center 的其中一項服務,底層是基於 Azure。

設置與安裝

  1. 全局安裝 App Center CLI

    npm install -g appcenter-cli
    
  2. 登入並配置 App Center 帳號

    appcenter login 
    

    執行以上命令後,系統會提示「Access code from browser」。此時,會自動開啟一個App Center的網頁。
    https://ithelp.ithome.com.tw/upload/images/20231012/20103365enDO2nJNMB.png
    選擇你的登入方式進行登錄。成功登入後,會看到一串token。複製這串token,然後貼上到之前的「Access code from browser」,按下Enter,即完成登入操作。
    https://ithelp.ithome.com.tw/upload/images/20231012/2010336584T4dEZAR2.png

  3. 創建APP
    進到https://appcenter.ms/ ,按add new app創建APP
    https://ithelp.ithome.com.tw/upload/images/20231012/201033652Q18aafpjR.png
    或是使用命令

    appcenter apps create -d <AppName> -o Android -p React-Native
    appcenter apps create -d <AppName> -o iOS -p React-Native
    
  4. 部署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>
    

    https://ithelp.ithome.com.tw/upload/images/20231012/20103365A3W9ouY9ib.png

整合CodePush至專案(IOS)

  1. 安裝

    npm install --save react-native-code-push
    cd ios && pod install
    
  2. AppDelegate.m,增加引入

    #import <CodePush/CodePush.h>
    

    找到

    return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
    

    修改為

    return [CodePush bundleURL];
    
  3. 整合key進專案
    Info.plist 新增一個CodePushDeploymentKey,string中放入key

    <key>CodePushDeploymentKey</key>
    <string>your key</string>
    

    不知道key的話,可以用以下指令查

    appcenter codepush deployment list --app <ownerName>/<appName> -k
    

整合CodePush至專案(Android)

  1. 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')
    
  2. android/app/build.gradle,新增:

    apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"
    
  3. 修改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();
            }
        };
    }
    
  4. 將key放到strings.xml

    <resources>
     <string name="app_name">AppName</string>
     <string moduleConfig="true" name="CodePushDeploymentKey">DeploymentKey</string>
    </resources>
    

CodePush API介紹

  • 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

  1. 引入CodePush

    import CodePush from 'react-native-code-push';
    
  2. 檢查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

https://ithelp.ithome.com.tw/upload/images/20231012/201033653wcdKfiQJ4.png

Install Metrics表示更新被多少用戶裝置安裝。

Description、Mandatory、App Version,這幾個是我們在發布時的可選項

  • description(-desc): 提供一個描述,說明此次的更新。例如,-desc "修復了登錄問題"。
  • mandatory(-m): 如果加上這個選項,那麼這次的更新會被標記為必須的。表示當用戶啟動應用時,他們將被強制更新到這個版本,不允許他們跳過它。
  • target-binary-version(-t):如果不指定,CodePush預設將會將該更新適用於所有版本的APP。一般來說在線上環境我們都會指定版本,因為不同的版本可能會有不同的JS和原生代碼結構,這可能會導致與更新不兼容的問題。

另外target-binary-version版本指的是原生的版本號,有些新手可能不太熟,順便說明一下查看原生版本號的方法:

  • iOS:
    打開.xcworkspace檔。在Xcode中,選擇你的專案,然後在主視窗中選擇General。在Identity部分,找到Version。
  • Android:
    打開android/app/build.gradle文件。找到versionName。

加上以上三個選項的發布範例:

appcenter codepush release-react -a <ownerName>/<appName> -d Staging -desc "修復了登錄問題" -m -t 1.2

Ref

https://learn.microsoft.com/zh-tw/appcenter/distribution/codepush/rn-get-started


上一篇
Day 26:React Native 中集成生物辨識
下一篇
Day 28:APP 圖標和啟動圖設定
系列文
30天React Native之旅:從入門到活用30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言