CodePush熱更新詳細接入教程

CodePush熱更新組件詳細接入教程

什麼是CodePush

CodePush是一個微軟開發的雲服務器。經過它,開發者能夠直接在用戶的設備上部署手機應用更新。CodePush至關於一箇中心倉庫,開發者能夠推送當前的更新(包括JS/HTML/CSS/IMAGE等)到CoduPush,而後應用將會查詢是否有更新。react

接入流程

  • 安裝 CodePush CLI
  • 註冊 CodePush帳號
  • 在CodePush服務器註冊App
  • RN代碼中集成CodePush
  • 原生應用中配置CodePush
  • 發佈更新的版本

CodePush 接入示例Demo地址:github.com/guangqiang-…

一、安裝 CodePush CLI

安裝CodePush指令,直接在終端上輸入以下命令便可,**注意:**這個CodePush指令只須要全局安裝一次便可,若是第一次安裝成功了,那後面就不在須要安裝android

$ npm install -g code-push-cliios

image

二、註冊 CodePush帳號

註冊CodePush帳號也很簡單,一樣是隻需簡單的執行下面的命令,一樣這個註冊操做也是全局只須要註冊一次便可git

$ code-push registergithub

**注意:**當執行完上面的命令後,會自動打開一個受權網頁,讓你選擇使用哪一種方式進行受權登陸,這裏咱們統一就選擇使用GitHub便可npm

image

當註冊成功後,CodePush會給咱們一個keyreact-native

image

咱們直接複製這個key,而後在終端中將這個key填寫進去便可,填寫key登陸成功顯示效果以下bash

image

咱們使用下面的命令來驗證個人登陸是否成功服務器

$ code-push loginapp

image

CodePush註冊登陸相關命令:

  • code-push login 登錄
  • code-push loout 註銷
  • code-push access-key ls 列出登錄的token
  • code-push access-key rm 刪除某個 access-key

三、在CodePush服務器註冊App

爲了讓CodePush服務器有咱們的App,咱們須要CodePush註冊App,輸入下面命令便可完成註冊,這裏須要注意若是咱們的應用分爲iOS和Android兩個平臺,這時咱們須要分別註冊兩套key 應用添加成功後就會返回對應的productionStaging 兩個key,production表明生產版的熱更新部署,Staging表明開發版的熱更新部署,在ios中將staging的部署key複製在info.plist的CodePushDeploymentKey值中,在android中複製在Application的getPackages的CodePush中

添加iOS平臺應用

$ code-push app add iOSRNHybrid ios react-native

image

添加Android平臺應用

$ code-push app add iOSRNHybridForAndroid Android react-native
複製代碼

image

咱們能夠輸入以下命令來查看咱們剛剛添加的App

$ code-push app list

image

CodePush管理App的相關命令:

  • code-push app add 在帳號裏面添加一個新的app
  • code-push app remove 或者 rm 在帳號裏移除一個app
  • code-push app rename 重命名一個存在app
  • code-push app list 或則 ls 列出帳號下面的全部app
  • code-push app transfer 把app的全部權轉移到另一個帳號

四、RN代碼中集成CodePush

首先咱們須要安裝CodeoPush組件,而後經過link命令添加原生依賴,最後在RN根組件中添加熱更新邏輯代碼

安裝組件

$ npm install react-native-code-push --save

image

添加原生依賴,這裏添加依賴咱們使用自動添加依賴的方式

$ react-native link react-native-code-push

image

咱們在RN項目的根組件中添加熱更新邏輯代碼以下

import React, { Component } from 'react';
import {
  Platform,
  StyleSheet,
  Text,
  View
} from 'react-native';

import CodePush from "react-native-code-push"; // 引入code-push

let codePushOptions = {
  //設置檢查更新的頻率
  //ON_APP_RESUME APP恢復到前臺的時候
  //ON_APP_START APP開啓的時候
  //MANUAL 手動檢查
  checkFrequency : CodePush.CheckFrequency.ON_APP_RESUME
};

const instructions = Platform.select({
  ios: 'Press Cmd+R to reload,\n' +
    'Cmd+D or shake for dev menu',
  android: 'Double tap R on your keyboard to reload,\n' +
    'Shake or press menu button for dev menu',
});

type Props = {};

class App extends Component<Props> {

  //若是有更新的提示
  syncImmediate() {
    CodePush.sync( {
          //安裝模式
          //ON_NEXT_RESUME 下次恢復到前臺時
          //ON_NEXT_RESTART 下一次重啓時
          //IMMEDIATE 立刻更新
          installMode : CodePush.InstallMode.IMMEDIATE ,
          //對話框
          updateDialog : {
            //是否顯示更新描述
            appendReleaseDescription : true ,
            //更新描述的前綴。 默認爲"Description"
            descriptionPrefix : "更新內容:" ,
            //強制更新按鈕文字,默認爲continue
            mandatoryContinueButtonLabel : "當即更新" ,
            //強制更新時的信息. 默認爲"An update is available that must be installed."
            mandatoryUpdateMessage : "必須更新後才能使用" ,
            //非強制更新時,按鈕文字,默認爲"ignore"
            optionalIgnoreButtonLabel : '稍後' ,
            //非強制更新時,確認按鈕文字. 默認爲"Install"
            optionalInstallButtonLabel : '後臺更新' ,
            //非強制更新時,檢查到更新的消息文本
            optionalUpdateMessage : '有新版本了,是否更新?' ,
            //Alert窗口的標題
            title : '更新提示'
          } ,
        } ,
    );
  }

  componentWillMount() {
    CodePush.disallowRestart();//禁止重啓
    this.syncImmediate(); //開始檢查更新
  }

  componentDidMount() {
    CodePush.allowRestart();//在加載完了,容許重啓
  }

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
        <Text style={styles.instructions}>
          To get started, edit App.js
        </Text>
        <Text style={styles.instructions}>
          {instructions}
        </Text>

        <Text style={styles.instructions}>
          這是更新的版本
        </Text>
      </View>
    );
  }
}

// 這一行必需要寫
App = CodePush(codePushOptions)(App)

export default App

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
})
複製代碼

五、原生應用中配置CodePush

這裏原生應用中配置CodePush咱們須要分別配置iOS平臺和Android平臺

配置iOS平臺

  • 使用Xcode打開項目,Xcode的項目導航視圖中的PROJECT下選擇你的項目,選擇Info頁籤 ,在Configurations節點下單擊 + 按鈕 ,選擇Duplicate "Release Configaration,輸入Staging

image

  • 選擇Build Settings tab,搜索Build Location -> Per-configuration Build Products Path -> Staging,將以前的值:$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 改成:$(BUILD_DIR)/Release$(EFFECTIVE_PLATFORM_NAME)

image

  • 選擇Build Settings tab,點擊 + 號,選擇Add User-Defined Setting,將key設置爲CODEPUSH_KEY,Release 和 Staging的值爲前面建立的key,咱們直接複製進去便可

image

  • 打開Info.plist文件,在CodePushDeploymentKey中輸入$(CODEPUSH_KEY),並修改Bundle versions爲三位

image

iOS平臺CodePush環境集成完畢

配置Android平臺

六、發佈更新的版本

在使用以前須要考慮的是檢查更新時機,更新是否強制,更新是否要求即時等

更新時機

通常常見的應用內更新時機分爲兩種,一種是打開App就檢查更新,一種是放在設置界面讓用戶主動檢查更新並安裝

  • 打開APP就檢查更新

    最爲簡單的使用方式在React Natvie的根組件的componentDidMount方法中經過 codePush.sync()(須要先導入codePush包:import codePush from 'react-native-code-push')方法檢查並安裝更新,若是有更新包可供下載則會在重啓後生效。不過這種下載和安裝都是靜默的,即用戶不可見。若是須要用戶可見則須要額外的配置。具體能夠參考codePush官方API文檔,部分代碼,完整代碼請參照文檔上面

    codePush.sync({
      updateDialog: {
        appendReleaseDescription: true,
        descriptionPrefix:'\n\n更新內容:\n',
        title:'更新',
        mandatoryUpdateMessage:'',
        mandatoryContinueButtonLabel:'更新',
      },
      mandatoryInstallMode:codePush.InstallMode.IMMEDIATE,
      deploymentKey: CODE_PUSH_PRODUCTION_KEY,
    });
    複製代碼

    上面的配置在檢查更新時會彈出提示對話框, mandatoryInstallMode表示強制更新,appendReleaseDescription表示在發佈更新時的描述會顯示到更新對話框上讓用戶可見

  • 用戶點擊檢查更新按鈕

    在用戶點擊檢查更新按鈕後進行檢查,若是有更新則彈出提示框讓用戶選擇是否更新,若是用戶點擊當即更新按鈕,則會進行安裝包的下載(實際上這時候應該顯示下載進度,這裏省略了)下載完成後會當即重啓並生效(也可配置稍後重啓),部分代碼以下

    codePush.checkForUpdate(deploymentKey).then((update) => {
        if (!update) {
            Alert.alert("提示", "已經是最新版本--", [
                {
                    text: "Ok", onPress: () => {
                    console.log("點了OK");
                }
                }
            ]);
        } else {
            codePush.sync({
                    deploymentKey: deploymentKey,
                    updateDialog: {
                        optionalIgnoreButtonLabel: '稍後',
                        optionalInstallButtonLabel: '當即更新',
                        optionalUpdateMessage: '有新版本了,是否更新?',
                        title: '更新提示'
                    },
                    installMode: codePush.InstallMode.IMMEDIATE,
    
                },
                (status) => {
                    switch (status) {
                        case codePush.SyncStatus.DOWNLOADING_PACKAGE:
                            console.log("DOWNLOADING_PACKAGE");
                            break;
                        case codePush.SyncStatus.INSTALLING_UPDATE:
                            console.log(" INSTALLING_UPDATE");
                            break;
                    }
                },
                (progress) => {
                    console.log(progress.receivedBytes + " of " + progress.totalBytes + " received.");
                }
            );
        }
     }
    複製代碼

更新是否強制

若是是強制更新須要在發佈的時候指定,發佈命令中配置--m true

更新是否要求即時

在更新配置中經過指定installMode來決定安裝完成的重啓時機,亦即更新生效時機

  • codePush.InstallMode.IMMEDIATE :安裝完成當即重啓更新
  • codePush.InstallMode.ON_NEXT_RESTART :安裝完成後會在下次重啓後進行更新
  • codePush.InstallMode.ON_NEXT_RESUME :安裝完成後會在應用進入後臺後重啓更新

如何發佈CodePush更新包

在將RN的bundle放到CodePush服務器以前,咱們須要先生成bundle,在將bundle上傳到CodePush

生成bundle

  • 咱們在RN項目根目錄下線建立bundle文件夾,再在bundle中建立建立ios和android文件夾,最後將生成的bundle文件和資源文件拖到咱們的項目工程中

image

  • 生成bundle命令 react-native bundle --platform 平臺 --entry-file 啓動文件 --bundle-output 打包js輸出文件 --assets-dest 資源輸出目錄 --dev 是否調試
$ react-native bundle --entry-file index.ios.js --bundle-output ./bundle/ios/main.jsbundle --platform ios --assets-dest ./bundle/ios --dev false
複製代碼

image

  • 將生成的bundle文件和資源文件拖到咱們的項目工程

image

上傳bundle

  • 將生成的bundle文件上傳到CodePush,咱們直接執行下面的命令便可

$ code-push release-react <Appname> <Platform> --t <本更新包面向的舊版本號> --des <本次更新說明>

注意: CodePush默認是更新Staging 環境的,若是發佈生產環境的更新包,須要指定--d參數:--d Production,若是發佈的是強制更新包,須要加上 --m true強制更新

$ code-push release-react iOSRNHybrid ios --t 1.0.0 --dev false --d Production --des "這是第一個更新包" --m true
複製代碼

更新包上傳到CodePush服務器成功後,效果圖以下:

image

查看發佈的歷史記錄,命令以下

查詢Production

$ code-push deployment history projectName Production

查詢Staging

$ code-push deployment history projectName Staging

image

對1.0.0版本的應用如何發佈第二個、第n個更新包

操做步驟和上面發佈第一個更新包流程同樣,咱們任然先須要打出bundle包,將生成的bundle文件和資源文件拖到工程中,而後再將bundle發佈到CodePush

$ react-native bundle --entry-file index.ios.js --bundle-output ./bundle/ios/main.jsbundle --platform ios --assets-dest ./bundle/ios --dev false
複製代碼
$ code-push release-react iOSRNHybrid ios --t 1.0.0 --dev false --d Production --des "這是第二個更新包" --m true
複製代碼

注意事項

  • 當咱們在生成更新包以前,咱們須要先將JS代碼打包成bundle,而後拖拽到項目中,打包以前咱們須要先本身創建輸出bundle的文件夾bundle -> ios,打bundle命令以下:
$ react-native bundle --entry-file index.ios.js --bundle-output ./bundle/ios/main.jsbundle --platform ios --assets-dest ./bundle/ios --dev false
複製代碼

image

  • 發佈更新包命令中的 -- t 對應的參數是和咱們項目中的版本號一致的,這個不要誤理解爲是更新包的版本號,例如項目中的版本號爲1.0.0, 這時若是咱們須要對這個1.0.0 版本的項目進行第一次熱更新,那麼命令中的 -- t 也爲1.0.0,第二次熱更新任然爲1.0.0

  • 項目的版本號須要改成三位的,默認是兩位的,可是CodePush須要三位數的版本號

  • 發佈更新應用時,應用的名稱必需要和以前註冊過的應用名稱一致

image

  • 建立應用時,信息要填寫正確

image

  • 當執行link,命令卡住不執行時,這時直接按回車鍵先ignore key便可

image

  • 還有最重要的一點須要注意的,就是打包證書環境要是良好的,證書不能報錯

福利時間

  • 做者React Native開源項目OneM地址(按照企業開發標準搭建框架完成開發的):github.com/guangqiang-…:歡迎小夥伴們 star
  • 做者簡書主頁:包含60+篇RN開發相關的技術文章www.jianshu.com/u/023338566… 歡迎小夥伴們:多多關注多多點贊
  • 做者React Native QQ技術交流羣:620792950 歡迎小夥伴進羣交流學習
  • 友情提示:在開發中有遇到RN相關的技術問題,歡迎小夥伴加入交流羣(620792950),在羣裏提問、互相交流學習。交流羣也按期更新最新的RN學習資料給你們,謝謝你們支持!
相關文章
相關標籤/搜索