CodePush是微軟提供的一套可用於React Native和Cordova的熱更新服務,國內也有相似的服務Pushy,從關注度和使用人數來講,CodePush完勝於Pushy(截至目前,CodePush在Github上Star數2900+,Pushy Star數600+,畢竟大公司的產品更讓開發者內心有底,但CodePush是否真的絕對比Pushy要好不作評價)javascript
使用命令npm install -g code-push-cli
安裝CodePush終端html
ps.都在開發React Native了,npm安裝就無需贅言了吧。java
CodePush終端安裝完成後就可使用code-push
命令了。
在終端輸入code-push register
,會跳轉受權網頁。在這個網頁能夠選擇Github。或者微軟做爲受權提供者,不過我以爲90%的開發者都會選擇Github。react
受權完成後,CodePush會顯示你的Access Key,複製輸入到終端便可完成註冊並登錄。
ps.只要不主動退出(經過code-push logout
命令),登錄狀態會一直有效。android
在終端輸入code-push app add <appName>
便可完成建立,註冊完成以後會返回一套deployment key,包括Staging和Production。該key在後面步驟中會用到。ios
心得:若是你的應用分爲Android和iOS版,那麼在向CodePush註冊應用的時候須要註冊兩個App獲取兩套deployment key,如:
code-push app add AppDemo-Androidgit
code-push app add AppDemo-iOS
由於發佈的時候使用的打包命令是有所不一樣的,所以須要作區分。github
code-push相關常見命令以下:npm
Usage: code-push app <command> 命令: add 建立一個新的App remove 刪除App rm 刪除App rename 重命名已經存在App list 列出與你帳戶關聯的全部App ls 列出與你帳戶關聯的全部App transfer 將一個App的全部權轉讓給另外一個賬戶
這裏跟進使用端分Android集成和iOS集成,但兩者都有共通的部分react-native
在React Native項目中安裝codePush依賴:npm install --save react-native-code-push
經過react-native link命令自動構建關聯,這裏會要求輸入 deployment key,直接Enter跳過便可,由於咱們會在後續步驟中經過更加靈活的方式配置
接下來的步驟,AndroidiOS有所不一樣,所以分開來講。
打開android/app/build.gradle文件,修改android-buildTypes節點成以下
buildTypes { debug{ //省略了其餘配置 buildConfigField "String", "CODEPUSH_KEY", '""' } releaseStaging { buildConfigField "String", "CODEPUSH_KEY", '"此處填寫Staging key"' } release { //省略了其餘配置 buildConfigField "String", "CODEPUSH_KEY", '"此處填寫Production key"' } }
在android/app/build.gradle設置好deployment-key以後呢,咱們就可使用了:
修改MainApplication.java文件中的getPackages()方法爲以下:
protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage(), new RCTSwipeRefreshLayoutPackage(), new VectorIconsPackage(), new CodePush(BuildConfig.CODEPUSH_KEY, MainApplication.this, BuildConfig.DEBUG)// Add/change this line. ); }
3.修改VersionName
在 android/app/build.gradle中有個 android.defaultConfig.versionName屬性,咱們須要把 應用版本改爲 三位,好比1.0,須要修改爲1.0.0
至此,CodePush在Android端的集成工做已經完成了。
使用Xcode打開項目,Xcode的項目導航視圖中的PROJECT下選擇你的項目, 選擇Info頁籤 ,在Configurations節點下單擊 + 按鈕 ,選擇Duplicate "Release Configaration , 輸入Staging。
在build Settings頁籤中單擊 + 按鈕而後選擇添加User-Defined Setting,而後輸入CODEPUSH_KEY(名稱隨意),而後填入deployment key。
ps.能夠經過
code-push deployment ls Flow800-Android -k
查看deployment key
3.打開 Info.plist文件,在CodePushDeploymentKey中輸入$(CODEPUSH_KEY),並修改Bundle versions爲三位,以下圖
至此,iOS端集成也完成了。
該配置的都已經配置完了,接下來就是使用了。
在使用以前須要考慮的是檢查更新時機,更新是否強制,更新是否要求即時等等。
通常常見的應用內更新時機分爲兩種,一種是打開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, });
上面的配置在檢查更新時會彈出提示對話框, mandatoryxxx表示強制更新,appendReleaseDescription表示在發佈更新時的描述會顯示到更新對話框上讓用戶可見
來個更加接近實際應用的:在用戶點擊檢查更新按鈕後進行檢查,若是有更新則彈出提示框讓用戶選擇是否更新,若是用戶點擊當即更新按鈕,則會進行安裝包的下載(實際上這時候應該顯示下載進度,這裏省略了)下載完成後會當即重啓並生效(也可配置稍後重啓)
ps.這裏面還有個神坑,下文再說。
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的更新包發佈其實很簡單。在終端輸入命令
code-push release-react <Appname> <Platform> --t <本更新包面向的舊版本號> --des <本次更新說明>
CodePush默認是更新 Staging 環境的,若是發佈生產環境的更新包,須要指定--d參數:--d Production
,若是發佈的是強制更新包,須要加上 --m true
強制更新
示例:
code-push release-react Flow800-Android android --t 2.0.0 --dev false --d Production --des "1.全新頁面\n2.上線流量商城\n3.已知bug修復" --m ture
經常使用部署命令以下:
Usage: code-push deployment <command> 命令: add 在已存在的App中建立一個部署 clear 清除與部署相關的發佈歷史記錄 remove 在App中刪除一個部署 rm 在App中刪除一個部署 rename 重命名一個已存在的部署 list 列出App中的全部部署 ls 列出App中的全部部署 history 列出一個部署的發佈歷史記錄 h 列出一個部署的發佈歷史記錄
至此,一個完整的發佈,檢查,安裝流程已經基本描述完了。下面來看下更新的效果:
在Android端進行調試時,在更新以前須要修改Debug Server地址和端口爲任意字符串,讓其訪問不到真正Debug Server,不然更新重啓後,就直接訪問了Debug Server致使新的安裝包沒有安裝上。
也能夠直接打Android離線包,這樣子就不須要理會Debug Server的影響
在iOS端調試時,須要打離線包並拖拽到Xcode工程中。
打包命令:
react-native bundle --entry-file index.ios.js --bundle-output ./bundle/ios/main.jsbundle --platform ios --assets-dest ./bundle/ios --dev false
拖拽完成後目錄結構如上。
此外,還須要對AppDelegate.m文件進行修改:
不然更新重啓後仍是舊版的App。
3.發佈更新包時,切記--t參數指定的是本次更新包的目標版本號,而不是本次更新包的版本號
4.若是不是在根組件的componentDidMount()方法經過codePush.sync()方法進行更新檢查與安裝,好比像我在設置中經過一個檢查更新按鈕,這時候就須要十分當心了。必須在根組件的componentDidMount()方法中添加 codePush.notifyAppReady()
,不然應用會出現第一次重啓是更新版,第二次重啓又回滾到舊版的現象。
5.一個App一般不會是一我的開發,所以codePush添加合做者是很常見的。經過 code-push collaborator
來操做合做者相關命令。
Usage: code-push collaborator <command> 命令: add 對指定的項目添加一個新的合做者 remove 刪除指定的項目中的合做者 rm 刪除指定的項目中的合做者 list 列出指定項目中的全部合做者 ls 列出指定項目中的全部合做者 示例: code-push collaborator add AppDemo foo@bar.com 添加一個合做者foo@bar.com到AppDemo這個App中
6.最後說一下CodePush的缺陷,由於是國外服務器,因此有時候下載速度並非很理想。此外CodePush如今是免費服務,之後會不會收費仍是個未知數。所以已經有人提出了自建codePush服務器,可見於此:code-push-server
更多常見問題及API使用方法請參見如下資料
微軟官方ReactNative CodePush文檔
React Native熱更新部署/熱更新-CodePush最新集成總結(新)
react-native-code-push Github基本上全部問題均可以在官方文檔或者github的issue中找到答案。