1. 程式人生 > >react-native熱更新之CodePush詳細介紹及使用方法

react-native熱更新之CodePush詳細介紹及使用方法

react-native熱更新之CodePush詳細介紹及使用方法

2018年03月04日 17:03:21  閱讀數:7979 標籤: react native熱更新code pushJSRN 個人分類: react native  

React Native應用部署/熱更新-CodePush最新整合總結

React Native應用部署/熱更新-CodePush最新整合總結(新)

 

 

本文出自《React Native學習筆記》系列文章。
瞭解更多,可以關注我的GitHub和加入:
React Native學習交流群 

React Native學習交流群 React Native學習交流群

 


更新說明:
此次博文更新適配了最新版的CodePush v1.17.0;添加了iOS的整合方式與除錯技巧;添加了更為簡潔的CodePush釋出更新的方式以及進行了一些其他的優化。

React Native的出現為移動開發領域帶來了兩大革命性的創新:

  1. 整合了移動端APP的開發,不僅縮短了APP的開發時間,也提高了APP的開發效率。
  2. 為移動APP動態更新提供了基礎。

本文將向大家分享React Natvie應用部署/動態更新方面的內容。

React Native支援大家用React Native技術開發APP,並打包生成一個APP。在動態更新方面React Native只是提供了動態更新的基礎,對將應用部署到哪裡,如何進行動態更新並沒有支援的那麼完善。好在微軟開發了CodePush,填補React Native 應用在動態更新方面的空白。CodePush 是微軟提供的一套用於熱更新 React Native 和 Cordova 應用的服務。下面將向大家分享如何使用CodePush實時更新你的應用,後期會分享不採用CodePush,如何自己去實現React Native應用熱更新。

CodePush簡介

CodePush 是微軟提供的一套用於熱更新 React Native 和 Cordova 應用的服務。
CodePush 是提供給 React Native 和 Cordova 開發者直接部署移動應用更新給使用者裝置的雲服務。CodePush 作為一箇中央倉庫,開發者可以推送更新 (JS, HTML, CSS and images),應用可以從客戶端 SDK 裡面查詢更新。CodePush 可以讓應用有更多的可確定性,也可以讓你直接接觸使用者群。在修復一些小問題和新增新特性的時候,不需要經過二進位制打包,可以直接推送程式碼進行實時更新。

CodePush 可以進行實時的推送程式碼更新:

  • 直接對使用者部署程式碼更新
  • 管理 Alpha,Beta 和生產環境應用
  • 支援 React Native 和 Cordova
  • 支援JavaScript 檔案與圖片資源的更新

CodePush開源了react-native版本,react-native-code-push託管在GitHub上。

安裝與註冊CodePush

使用CodePush之前首先要安裝CodePush客戶端。本文以OSX 10.11.5作為平臺進行演示。

安裝 CodePush CLI

管理 CodePush 賬號需要通過 NodeJS-based CLI。
只需要在終端輸入 npm install -g code-push-cli,就可以安裝了。
安裝完畢後,輸入 code-push -v檢視版本,如看到版本代表成功。
![安裝 CodePush CLI成功](https://raw.githubusercontent.com/crazycodeboy/RNStudyNotes/master/React%20Native應用部署、熱更新-CodePush最新整合總結/images/安裝 CodePush CLI成功.png)
目前我的版本是 1.12.1-beta

PS. 
npm為NodeJS的包管理器,如果你沒安裝NodeJS請先安裝。

建立一個CodePush 賬號

在終端輸入code-push register,會開啟如下注冊頁面讓你選擇授權賬號。

註冊codepush 註冊codepush
授權通過之後,CodePush會告訴你“access key”,複製此key到終端即可完成註冊。
![獲取codepush access key]( https://raw.githubusercontent.com/crazycodeboy/RNStudyNotes/master/React%20Native應用部署、熱更新-CodePush最新整合總結/images/獲取codepush access key.png)
然後終端輸入 code-push login進行登陸,登陸成功後,你的session檔案將會寫在 /Users/你的使用者名稱/.code-push.config。
登陸成功 登陸成功

 

PS.相關命令

  • code-push login 登陸
  • code-push loout 登出
  • code-push access-key ls 列出登陸的token
  • code-push access-key rm <accessKye> 刪除某個 access-key

在CodePush伺服器註冊app

為了讓CodePush伺服器知道你的app,我們需要向它註冊app: 在終端輸入code-push app add <appName>即可完成註冊。

code-push-add-app code-push-add-app

註冊完成之後會返回一套deployment key,該key在後面步驟中會用到。

心得:如果你的應用分為Android和iOS版,那麼在向CodePush註冊應用的時候需要註冊兩個App獲取兩套deployment key,如:

  1.   code- push app add MyApp-Android
  2.   code- push app add MyApp-iOS

PS.相關命令

  • 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的所有權轉移到另外一個賬號

整合CodePush SDK

Android

下面我們通過如下步驟在Android專案中整合CodePush。
第一步:在專案中安裝 react-native-code-push外掛,終端進入你的專案根目錄然後執行
npm install --save react-native-code-push

第二步:在Android project中安裝外掛。
CodePush提供了兩種方式:RNPM 和 Manual,本次演示所使用的是RNPM。
執行npm i -g rnpm,來安裝RNPM。

在React Native v0.27及以後版本RNPM已經被整合到了 React Native CL中,就不需要再進行安裝了。

第三步: 執行 rnpm link react-native-code-push。這條命令將會自動幫我們在anroid檔案中新增好設定。

react-native-code-push has been successfully linked react-native-code-push has been successfully linked

在終端執行此命令之後,終端會提示讓你輸入deployment key,這是你只需將你的deployment Staging key輸入進去即可,如果不輸入則直接單擊enter跳過即可。

第四步: 在 android/app/build.gradle檔案裡面添如下程式碼:

  1.   apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"
  2.  然後在/android/settings.gradle中新增如下程式碼:
  3.   include ':react-native-code-push'
  4.   project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')

第五步: 執行 code-push deployment -k ls <appName>獲取 部署祕鑰。預設的部署名是 staging,所以 部署祕鑰(deployment key ) 就是 staging。
第六步: 新增配置。當APP啟動時我們需要讓app向CodePush諮詢JS bundle的所在位置,這樣CodePush就可以控制版本。更新 MainApplication.java檔案:

  1.   public class MainApplication extends Application implements ReactApplication {
  2.  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
  3.  @Override
  4.  protected boolean getUseDeveloperSupport() {
  5.  return BuildConfig.DEBUG;
  6.  }
  7.  @Override
  8.  protected String getJSBundleFile() {
  9.  return CodePush.getJSBundleFile();
  10.  }
  11.  @Override
  12.  protected List<ReactPackage> getPackages() {
  13.  // 3. Instantiate an instance of the CodePush runtime and add it to the list of
  14.  // existing packages, specifying the right deployment key. If you don't already
  15.  // have it, you can run "code-push deployment ls <appName> -k" to retrieve your key.
  16.  return Arrays.<ReactPackage>asList(
  17.  new MainReactPackage(),
  18.  new CodePush( "deployment-key-here", MainApplication.this, BuildConfig.DEBUG)
  19.  );
  20.  }
  21.  };
  22.  @Override
  23.  public ReactNativeHost getReactNativeHost() {
  24.  return mReactNativeHost;
  25.  }
  26.   }  

關於deployment-key的設定

在上述程式碼中我們在建立CodePush例項的時候需要設定一個deployment-key,因為deployment-key分生產環境與測試環境兩種,所以建議大家在build.gradle中進行設定。在build.gradle中的設定方法如下:

開啟android/app/build.gradle檔案,找到android { buildTypes {} }然後新增如下程式碼即可:

  1.   android {
  2.  ...
  3.  buildTypes {
  4.  debug {
  5.  ...
  6.  // CodePush updates should not be tested in Debug mode
  7.  ...
  8.  }  
  9.  releaseStaging {
  10.  ...
  11.  buildConfigField "String", "CODEPUSH_KEY", '"<INSERT_STAGING_KEY>"'
  12.  ...
  13.  }  
  14.  release {
  15.  ...
  16.  buildConfigField "String", "CODEPUSH_KEY", '"<INSERT_PRODUCTION_KEY>"'
  17.  ...
  18.  }
  19.  }
  20.  ...
  21.   } 

心得:另外,我們也可以將deployment-key存放在local.properties中:

  1.  code_push_key_production=erASzHa1-wTdODdPJDh6DBF2Jwo94JFH08Kvb
  2.  code_push_key_staging=mQY75RkFbX6SiZU1kVT1II7OqWst4JFH08Kvb

如圖:


local.properties存放codepush-key local.properties存放codepush-key

然後在就可以在android/app/build.gradle可以通過下面方式來引用它了:

  1.   Properties properties = new Properties()
  2.   properties.load(project.rootProject.file('local.properties').newDataInputStream())
  3.   android {
  4.  ...
  5.  buildTypes {
  6.  debug {
  7.  ...
  8.  // CodePush updates should not be tested in Debug mode
  9.  ...
  10.  }  
  11. releaseStaging {
  12.  ...
  13.  buildConfigField "String", "CODEPUSH_KEY", '"'+properties.getProperty("code_push_key_production")+'"'
  14.  ...
  15.  }   
  16. release {
  17.  ...
  18.  buildConfigField "String", "CODEPUSH_KEY", '"'+properties.getProperty("code_push_key_staging")+'"'
  19.  ...
  20.  }
  21.  }
  22.  ...
  23.   }  

在android/app/build.gradle設定好deployment-key之後呢,我們就可以這樣使用了:

  1.   @Override
  2.   protected List<ReactPackage> getPackages() {
  3.  return Arrays.<ReactPackage>asList(
  4.  ...
  5.  new CodePush(BuildConfig.CODEPUSH_KEY, MainApplication. this, BuildConfig.DEBUG), // Add/change this line.
  6.  ...
  7.  );
  8.   } 

第七步:修改versionName。
在 android/app/build.gradle中有個 android.defaultConfig.versionName屬性,我們需要把 應用版本改成 1.0.0(預設是1.0,但是codepush需要三位數)。

  1.  android{
  2.  defaultConfig{
  3.  versionName "1.0.0"
  4.  }
  5.  }

至此Code Push for Android的SDK已經整合完成。

iOS

CodePush官方提供RNPM、CocoaPods與手動三種在iOS專案中整合CodePush的方式,接下來我就以RNPM的方式來講解一下如何在iOS專案中整合CodePush。

第一步:在專案中安裝react-native-code-push外掛,終端進入你的專案根目錄然後執行

  1.   npm install --save react-native-code-push  

第二步: 執行 rnpm link react-native-code-push。這條命令將會自動幫我們在ios中新增好設定。

在終端執行此命令之後,終端會提示讓你輸入deployment key,這是你只需將你的deployment Staging key輸入進去即可,如果不輸入則直接單擊enter跳過即可。

關於deployment-key的設定

在我們想CodePush註冊App的時候,CodePush會給我們兩個deployment-key分別是在生產環境與測試環境時使用的,我們可以通過如下步驟來設定deployment-key。

1.用Xcode 開啟專案 ➜ Xcode的專案導航檢視中的PROJECT下選擇你的專案 ➜ 選擇Info頁籤 ➜ 在Configurations節點下單擊 + 按鈕 ➜ 選擇Duplicate "Release ➜ 輸入Staging(名稱可以自定義);

Duplicate-Release-Staging.png Duplicate-Release-Staging.png

 

2.然後選擇Build Settings頁籤 ➜ 單擊 + 按鈕然後選擇新增User-Defined Setting

新增User-Defined-Setting 新增User-Defined-Setting

3.然後輸入CODEPUSH_KEY(名稱可以自定義)

設定Staging deployment key 設定Staging deployment key

提示:你可以通過code-push deployment ls <APP_NAME> -k命令來檢視deployment key。

4.開啟 Info.plist檔案,在CodePushDeploymentKey列的Value中輸入$(CODEPUSH_KEY)

引用CODEPUSH_KEY 引用CODEPUSH_KEY

到目前為止,iOS的設定已經完成了,和在Android上的整合相比是不是簡單了很多呢。

使用CodePush進行熱更新

設定更新策略

在使用CodePush更新你的應用之前需要,先配置一下更新控制策略,即:

  • 什麼時候檢查更新?(在APP啟動的時候?在設定頁面新增一個檢查更新按鈕?)
  • 什麼時候可以更新,如何將更新呈現給終端使用者?

最簡單的方式是在根component中進行上述策略控制。

  1. 在 js中載入 CodePush模組:
    import codePush from 'react-native-code-push' 
    2.在 componentDidMount中呼叫 sync方法,後臺請求更新
    codePush.sync()

如果可以進行更新,CodePush會在後臺靜默地將更新下載到本地,等待APP下一次啟動的時候應用更新,以確保使用者看到的是最新版本。
如果更新是強制性的,更新檔案下載好之後會立即進行更新。
如果你期望更及時的獲得更新,可以在每次APP從後臺進入前臺的時候去主動的檢查更新:
在應用的根component的componentDidMount中新增如下程式碼:

  1.   AppState.addEventListener("change", (newState) => {
  2.  newState === "active" && codePush.sync();
  3.   }); 

釋出更新

CodePush支援兩種釋出更新的方式,一種是通過code-push release-react簡化方式,另外一種是通過code-push release的複雜方式。

第一種方式:通過code-push release-react釋出更新

這種方式將打包與釋出兩個命令合二為一,可以說大大簡化了我們的操作流程,建議大家多使用這種方式來發布更新。

命令格式:

code-push release-react <appName> <platform> 

eg:

  1.  code- push release-react MyApp-iOS ios
  2.  code- push release-react MyApp-Android android

再來個更高階的:

code-push release-react MyApp-iOS ios  --t 1.0.0 --dev false --d Production --des "1.優化操作流程" --m true

其中引數--t為二進位制(.ipa與apk)安裝包的的版本;--dev為是否啟用開發者模式(預設為false);--d是要釋出更新的環境分Production與Staging(預設為Staging);--des為更新說明;--m 是強制更新。

關於code-push release-react更多可選的引數,可以在終端輸入code-push release-react進行檢視。

另外,我們可以通過code-push deployment ls <appName>來檢視釋出詳情與此次更新的安裝情況。

第二中方式:通過code-push release釋出更新

code-push release釋出更新呢我們首先需要將js與圖片資源進行打包成 bundle。

生成bundle

釋出更新之前,需要先把 js打包成 bundle,如:

第一步: 在 工程目錄裡面新增 bundles檔案:mkdir bundles

第二步: 執行命令打包 react-native bundle --platform 平臺 --entry-file 啟動檔案 --bundle-output 打包js輸出檔案 --assets-dest 資源輸出目錄 --dev 是否除錯
eg:
react-native bundle --platform android --entry-file index.android.js --bundle-output ./bundles/index.android.bundle --dev false

生成bundle 生成bundle

需要注意的是:

  • 忽略了資源輸出是因為 輸出資原始檔後,會把bundle檔案覆蓋了。
  • 輸出的bundle檔名不叫其他,而是 index.android.bundle,是因為 在debug模式下,工程讀取的bundle就是叫做 index.android.bundle。
  • 平臺可以選擇 android 或者 ios。

釋出更新

打包bundle結束後,就可以通過CodePush釋出更新了。在終端輸入
code-push release <應用名稱> <Bundles所在目錄> <對應的應用版本> --deploymentName: 更新環境 --description: 更新描述 --mandatory: 是否強制更新 
eg:
code-push release GitHubPopular ./bundles/index.android.bundle 1.0.6 --deploymentName Production --description "1.支援文章快取。" --mandatory true

推送更新到CodePush 推送更新到CodePush

 

注意:

  1. CodePush預設是更新 staging 環境的,如果是staging,則不需要填寫 deploymentName。
  2. 如果有 mandatory 則Code Push會根據mandatory 是true或false來控制應用是否強制更新。預設情況下mandatory為false即不強制更新。
  3. 對應的應用版本(targetBinaryVersion)是指當前app的版本(對應build.gradle中設定的versionName "1.0.6"),也就是說此次更新的js/images對應的是app的那個版本。不要將其理解為這次js更新的版本。
    如客戶端版本是 1.0.6,那麼我們對1.0.6的客戶端更新js/images,targetBinaryVersion填的就是1.0.6。
  4. 對於對某個應用版本進行多次更新的情況,CodePush會檢查每次上傳的 bundle,如果在該版本下如1.0.6已經存在與這次上傳完全一樣的bundle(對應一個版本有兩個bundle的md5完全一樣),那麼CodePush會拒絕此次更新。
    如圖:
    對應一個版本有兩個bundle的md5完全一樣 對應一個版本有兩個bundle的md5完全一樣

所以如果我們要對某一個應用版本進行多次更新,只需要上傳與上次不同的bundle/images即可。如:
eg:
對1.0.6的版本進行第一次更新:
code-push release GitHubPopular ./bundles/index.android.bundle 1.0.6 --deploymentName Production --description "1.支援文章快取。" --mandatory true 
對1.0.6的版本進行第二次更新:
code-push release GitHubPopular ./bundles/index.android.bundle 1.0.6 --deploymentName Production --description "1.新新增收藏功能。" --mandatory true

  1. 在終端輸入 code-push deployment history <appName> Staging 可以看到Staging版本更新的時間、描述等等屬性。
    eg:
    code-push release Equipment ./bundles 1.0.1

下面我們啟動事先安裝好的應用,看有什麼反應:

提示更新 提示更新
應用啟動之後,從CodePush伺服器查詢更新,並下載到本地,下載好之後,提示使用者進行更新。這就是CodePush用於熱更新的整個過程。

 

更多部署APP相關命令

  • code-push deployment add <appName> 部署
  • code-push deployment rename <appName> 重新命名
  • code-push deployment rm <appName> 刪除部署
  • code-push deployment ls <appName> 列出應用的部署情況
  • code-push deployment ls <appName> -k 檢視部署的key
  • code-push deployment history <appName> <deploymentNmae> 檢視歷史版本(Production 或者 Staging)

除錯技巧

如果你用模擬器進行除錯CodePush,在預設情況下是無法達到除錯效果的,因為在開發環境下裝在模擬器上的React Native應用每次啟動時都會從NodeJS伺服器上獲取最新的bundle,所以還沒等CodePush從伺服器將更新包下載下來時,APP就已經從NodeJS伺服器完成了更新。

Android

為規避這個問題在Android可以將開發環境的除錯地址改為一個不可用的地址,如下圖:

 

解決NodeJS對CodePush的影響 解決NodeJS對CodePush的影響
這樣APP就無法連線到NodeJS伺服器了,自然也就不能從NodeJS伺服器下載bundle進行更新了,它也只能乖乖的等待從CodePush伺服器下載更新包進行更新了。

 

iOS

在iOS中我們需要上文中講到的生成bundle,將bundle包與相應的圖片資源拖到iOS專案中如圖:

匯入bundle到xcode 匯入bundle到xcode

然後呢,我們需要在AppDelegate.m中進行如下修改:

  1.  // #ifdef DEBUG
  2.  // jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@ "index.ios" fallbackResource:nil];
  3.  // #else
  4.  jsCodeLocation = [CodePush bundleURL];
  5.  // #endif

讓React Native通過CodePush去獲取bundle包即可。

JavaScript API Reference

  • allowRestart
  • checkForUpdate
  • disallowRestart
  • getUpdateMetadata
  • notifyAppReady
  • restartApp
  • sync

其實我們可以將這些API分為兩類,一類是自動模式,一類是手動模式。

自動模式

sync為自動模式,呼叫此方法CodePush會幫你完成一系列的操作。其它方法都是在手動模式下使用的。
codePush.sync 
codePush.sync(options: Object, syncStatusChangeCallback: function(syncStatus: Number), downloadProgressCallback: function(progress: DownloadProgress)): Promise<Number>; 
通過呼叫該方法CodePush會幫我們自動完成檢查更新,下載,安裝等一系列操作。除非我們需要自定義UI表現,不然直接用這個方法就可以了。
sync方法,提供瞭如下屬性以允許你定製sync方法的預設行為

  • deploymentKey (String): 部署key,指定你要查詢更新的部署祕鑰,預設情況下該值來自於Info.plist(Ios)和MianActivity.java(Android)檔案,你可以通過設定該屬性來動態查詢不同部署key下的更新。
  • installMode (codePush.InstallMode): 安裝模式,用在向CodePush推送更新時沒有設定強制更新(mandatory為true)的情況下,預設codePush.InstallMode.ON_NEXT_RESTART即下一次啟動的時候安裝。
  • mandatoryInstallMode (codePush.InstallMode):強制更新,預設codePush.InstallMode.IMMEDIATE。
  • minimumBackgroundDuration (Number):該屬性用於指定app處於後臺多少秒才進行重啟已完成更新。預設為0。該屬性只在installModeInstallMode.ON_NEXT_RESUME情況下有效。
  • updateDialog (UpdateDialogOptions) :可選的,更新的對話方塊,預設是null,包含以下屬性
    • appendReleaseDescription (Boolean) - 是否顯示更新description,預設false
    • descriptionPrefix (String) - 更新說明的字首。 預設是” Description: “
    • mandatoryContinueButtonLabel (String) - 強制更新的按鈕文字. 預設 to “Continue”.
    • mandatoryUpdateMessage (String) - 強制更新時,更新通知. Defaults to “An update is available that must be installed.”.
    • optionalIgnoreButtonLabel (String) - 非強制更新時,取消按鈕文字. Defaults to “Ignore”.
    • optionalInstallButtonLabel (String) - 非強制更新時,確認文字. Defaults to “Install”.
    • optionalUpdateMessage (String) - 非強制更新時,更新通知. Defaults to “An update is available. Would you like to install it?”.
    • title (String) - 要顯示的更新通知的標題. Defaults to “Update available”.

eg:

  1.   codePush.sync({
  2.  updateDialog: {
  3.  appendReleaseDescription: true,
  4.  descriptionPrefix: '\n\n更新內容:\n',
  5.   title:'更新',
  6.   mandatoryUpdateMessage:'',
  7.   mandatoryContinueButtonLabel:'更新',
  8.  },
  9.  mandatoryInstallMode:codePush.InstallMode.IMMEDIATE,
  10.  deploymentKey: CODE_PUSH_PRODUCTION_KEY,
  11.  });  

手動模式

codePush.allowRestart

codePush.allowRestart(): void; 
允許重新啟動應用以完成更新。
如果一個CodePush更新將要發生並且需要重啟應用(e.g.設定了InstallMode.IMMEDIATE模式),但由於呼叫了disallowRestart方法而導致APP無法通過重啟來完成更新,
可以呼叫此方法來解除disallowRestart限制。
但在如下四種情況下,CodePush將不會立即重啟應用:

  1. 自上一次disallowRestart被呼叫,沒有新的更新。
  2. 有更新,但installModeInstallMode.ON_NEXT_RESTART的情況下。
  3. 有更新,但installModeInstallMode.ON_NEXT_RESUME,並且程式一直處於前臺,並沒有從後臺切換到前臺的情況下。
  4. 自從上次disallowRestart被呼叫,沒有再呼叫restartApp

codePush.checkForUpdate

codePush.checkForUpdate(deploymentKey: String = null): Promise<RemotePackage>; 
向CodePush伺服器查詢是否有更新。
該方法返回Promise,有如下兩種值:

  • null 沒有更新
    通常有如下情況導致RemotePackage為null:

    1. 當前APP版本下沒有部署新的更新版本。也就是說沒有想CodePush伺服器推送基於當前版本的有關更新。
    2. CodePush上的更新和使用者當前所安裝的APP版本不匹配。也就是說CodePush伺服器上有更新,但該更新對應的APP版本和使用者安裝的當前版本不對應。
    3. 當前APP已將安裝了最新的更新。
    4. 部署在CodePush上可用於當前APP版本的更新被標記成了不可用。
    5. 部署在CodePush上可用於當前APP版本的更新是"active rollout"狀態,並且當前的裝置不在有資格更新的百分比的裝置之內。
  • A RemotePackage instance
    有更新可供下載。

eg:

  1.   codePush.checkForUpdate()
  2.   .then((update) => {
  3.  if (!update) {
  4.   console.log("The app is up to date!");
  5.  } else {
  6.  console.log( "An update is available! Should we download it?");
  7.  }
  8.   });  

codePush.disallowRestart

codePush.disallowRestart(): void; 
不允許立即重啟用於以完成更新。
eg:

  1.   class OnboardingProcess extends Component {
  2.  ...   
  3. componentWillMount() {
  4.  // Ensure that any CodePush updates which are
  5.  // synchronized in the background can't trigger
  6.  // a restart while this component is mounted.
  7.  codePush.disallowRestart();
  8.  }  
  9.  componentWillUnmount() {
  10.  // Reallow restarts, and optionally trigger 
  11. // a restart if one was currently pending. 
  12. codePush.allowRestart();
  13.  }  
  14.  ...
  15.   }  

codePush.getUpdateMetadata 
codePush.getUpdateMetadata(updateState: UpdateState = UpdateState.RUNNING): Promise<LocalPackage>; 
獲取當前已安裝更新的元資料(描述、安裝時間、大小等)。
eg:

  1.   // Check if there is currently a CodePush update running, and if
  2.   // so, register it with the HockeyApp SDK (https://github.com/slowpath/react-native-hockeyapp)
  3.   // so that crash reports will correctly display the JS bundle version the user was running.
  4.   codePush.getUpdateMetadata().then((update) => {
  5.  if (update) {
  6.  hockeyApp.addMetadata({ CodePushRelease: update.label });
  7.  }
  8.   });  
  9.   // Check to see if there is still an update pending.
  10.   codePush.getUpdateMetadata(UpdateState.PENDING).then((update) => {
  11.  if (update) {
  12.  // There's a pending update, do we want to force a restart?
  13.  }
  14.   });  

codePush.notifyAppReady 
codePush.notifyAppReady(): Promise<void>; 
通知CodePush,一個更新安裝好了。當你檢查並安裝更新,(比如沒有使用sync方法去handle的時候),這個方法必須被呼叫。否則CodePush會認為update失敗,並rollback當前版本,在app重啟時。
當使用sync方法時,不需要呼叫本方法,因為sync會自動呼叫。

codePush.restartApp 
codePush.restartApp(onlyIfUpdateIsPending: Boolean = false): void; 
立即重啟app。
當以下情況時,這個方式是很有用的:

  1. app 當 呼叫 sync 或 LocalPackage.install 方法時,指定的 install mode是 ON_NEXT_RESTART 或 ON_NEXT_RESUME時 。 這兩種情況都是當app重啟或resume時,更新內容才能被看到。
  2. 在特定情況下,如使用者從其它頁面返回到APP的首頁時,這個時候呼叫此方法完成過更新對使用者來說不是特別的明顯。因為強制重啟,能馬上顯示更新內容。

總結

上文已經介紹了CodePush在動態更新方面的一些特性,但CodePush也存在著一些缺點:

  1. 伺服器在國外,在國內訪問,網速不是很理想。
  2. 其升級伺服器端程式並不開源的,後期微軟會不會對其收費還是個未知數。
    如果在沒有更好的動態更新React Native應用的方案的情況下,並且這些問題還在你的接受範圍之內的話,那麼CodePush可以作為動態更新React Native應用的一種選擇。
    後期會向大家分享不採用CodePush,自己搭建伺服器並實現React Native應用的動態更新相關的方案。

參考: 
http://microsoft.github.io/code-push/docs/getting-started.html
https://github.com/Microsoft/react-native-code-push

原文地址如下:

https://www.jianshu.com/p/28589c0be542?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation