ReactNative CodePush熱更新集成(OC+RN)

ReactNative 的熱更新主流的有ReactNative中文網(wǎng)的pushy和微軟的CodePush吏祸,經(jīng)過對比我選了CodePush意乓。這里CodePush是用的微軟的官方服務(wù),也可以用CodePush自行搭建服務(wù)呻惕。

CodePush 安裝與注冊

1.安裝 CodePush CLI

使用命令npm install -g code-push-cli安裝CodePush終端

ps.都在開發(fā)React Native了礁哄,npm安裝就無需贅言了吧映琳。


image.png

2.注冊CodePush 賬號

CodePush終端安裝完成后就可以使用code-push命令了浅侨。
在終端輸入code-push register纽谒,會跳轉(zhuǎn)授權(quán)網(wǎng)頁。在這個網(wǎng)頁可以選擇Github.

image.png

授權(quán)完成后如输,CodePush會顯示你的Access Key鼓黔,復(fù)制輸入到終端即可完成注冊并登陸。
ps.只要不主動退出(通過code-push logout命令)不见,登陸狀態(tài)會一直有效请祖。

image.png

在CodePush服務(wù)器中創(chuàng)建App

在終端輸入code-push app add <appName> <os> <platform>即可完成創(chuàng)建,注冊完成之后會返回一套deployment key脖祈,包括Staging和Production。該key在后面步驟中會用到刷晋。

image.png

因為發(fā)布的時候使用的打包命令是有所不同的盖高,因此需要做區(qū)分。

code-push相關(guān)常見命令如下:

Usage: code-push app <command>
命令:
  add       創(chuàng)建一個新的App
  remove    刪除App
  rm        刪除App
  rename    重命名已經(jīng)存在App
  list      列出與你賬戶關(guān)聯(lián)的所有App
  ls        列出與你賬戶關(guān)聯(lián)的所有App
  transfer  將一個App的所有權(quán)轉(zhuǎn)讓給另一個帳戶
  

CodePush集成

這里只講iOS集成

1.在React Native項目中安裝codePush依賴:npm install --save react-native-code-push

2.打開 Info.plist文件眼虱,在CodePushDeploymentKey中輸入deployment key喻奥,并修改Bundle versions為三位,如下圖

ps1:可以通過 code-push app ls查看所有已添加app

ps2:可以通過code-push deployment ls JWDemo-OC-RN -k查看deployment key)

1281528105033_.pic_hd.jpg

3.在OC項目中導(dǎo)入CodePush庫捏悬,如下圖:(CodePush需要指定podspec指向本地文件路徑)

image.png

4.設(shè)置bundle路徑:

#import <CodePush/CodePush.h>

//      NSURL *jsCodeLocation = [NSURL
//                                 URLWithString:@"http://localhost:8081/index.bundle?platform=ios"];

        NSURL *jsCodeLocation = [CodePush bundleURL];
        RCTRootView *rootView =
        [[RCTRootView alloc] initWithBundleURL : jsCodeLocation
                             moduleName        : @"MyReactNativeApp"
                             initialProperties : nil
                              launchOptions    : nil];
        
        UIViewController *vc = [[UIViewController alloc] init];
        vc.view = rootView;
        VC = vc;

ps:需要注意的是CodePush的bundleURL中的bundle名字為main撞蚕,所以需要將打出來的包名命名為main.jsbundle

遇到的坑:
使用[CodePush bundleURL]讀取bundle路徑時,首次打iOS原生包時过牙,需要將bundle包打入項目內(nèi)甥厦,
使用命令react-native bundle --entry-file index.js --platform ios --dev false --bundle-output ../Mars/bundle/main.jsbundle --assets-dest ../Mars/bundle將bundle包及資源文件打包,然后拖入原生項目中寇钉。特別注意:bundle文件夾及里面的main.jsbundle和main.jsbundle.meta 文件拖入是要選

image.png

然后移除assets文件夾對于項目的依賴刀疙,再將assets拖入工程如下圖選擇:

image.png

最終效果如下,assets文件夾應(yīng)該是藍色的:

image.png

如果不這樣做的話扫倡,首次運行會導(dǎo)致讀取不到資源文件或者bundle

使用react-native-code-psuh進行熱更新

該配置的都已經(jīng)配置完了谦秧,接下來就是使用了。
在使用之前需要考慮的是檢查更新時機,更新是否強制疚鲤,更新是否要求即時等等锥累。

更新時機
一般常見的應(yīng)用內(nèi)更新時機分為兩種,一種是打開APP就檢查更新集歇,一種是放在設(shè)置界面讓用戶主動檢查更新并安裝桶略。

打開APP就檢查更新
最為簡單的使用方式在React Natvie的根組件的componentDidMount方法中通過
codePush.sync()(需要先導(dǎo)入codePush包:import codePush from 'react-native-code-push')方法檢查并安裝更新,如果有更新包可供下載則會在重啟后生效鬼悠。不過這種下載和安裝都是靜默的删性,即用戶不可見。如果需要用戶可見則需要額外的配置焕窝。具體可以參考codePush官方API文檔蹬挺,下面是個人的一些實踐過的配置:

codePush.sync({
      updateDialog: {
        appendReleaseDescription: true,
        descriptionPrefix:'\n\n更新內(nèi)容:\n',
        title:'更新',
        mandatoryUpdateMessage:'',
        mandatoryContinueButtonLabel:'更新',
      },
      mandatoryInstallMode:codePush.InstallMode.IMMEDIATE,
      //deploymentKey: CODE_PUSH_PRODUCTION_KEY,//(若在原生項目中Info.plist設(shè)置了CodePushDeploymentKey則不需要在這里設(shè)置deploymentKey)
    });
    

上面的配置在檢查更新時會彈出提示對話框, mandatoryxxx表示強制更新它掂,appendReleaseDescription表示在發(fā)布更新時的描述會顯示到更新對話框上讓用戶可見

更新是否強制

如果是強制更新需要在發(fā)布的時候指定巴帮,發(fā)布命令中配置--m true,下文在細說

更新是否要求即時
在更新配置中通過指定installMode來決定安裝完成的重啟時機虐秋,亦即更新生效時機

codePush.InstallMode.IMMEDIATE:表示安裝完成立即重啟更新

codePush.InstallMode.ON_NEXT_RESTART:表示安裝完成后會在下次重啟后進行更新

codePush.InstallMode.ON_NEXT_RESUME:表示安裝完成后會在應(yīng)用進入后臺后重啟更新

發(fā)布codepush更新包

codepush的更新包發(fā)布其實很簡單榕茧。在終端輸入命令

code-push release-react <appName> <platform> [options]

CodePush默認(rèn)是更新 Staging 環(huán)境的,如果發(fā)布生產(chǎn)環(huán)境的更新包客给,需要指定--d參數(shù):--d Production 用押,如果發(fā)布的是強制更新包,需要加上 --m true強制更新

示例:

code-push release-react Demo-RN-OC ios --t 3.0.1 --dev false --d Staging --des “測試文案”

選項:

Usage: code-push release-react <appName> <platform> [options]


  --bundleName, -b           Name of the generated JS bundle file. If unspecified, the standard bundle name will be used, depending on the specified platform: "main.jsbundle" (iOS), "index.android.bundle" (Android) or "index.windows.bundle" (Windows)  [字符串] [默認(rèn)值: null]
  --deploymentName, -d       Deployment to release the update to  [字符串] [默認(rèn)值: "Staging"]
  --description, --des       Description of the changes made to the app with this release  [字符串] [默認(rèn)值: null]
  --development, --dev       Specifies whether to generate a dev or release build  [布爾] [默認(rèn)值: false]
  --disabled, -x             Specifies whether this release should be immediately downloadable  [布爾] [默認(rèn)值: false]
  --entryFile, -e            Path to the app's entry Javascript file. If omitted, "index.<platform>.js" and then "index.js" will be used (if they exist)  [字符串] [默認(rèn)值: null]
  --gradleFile, -g           Path to the gradle file which specifies the binary version you want to target this release at (android only).  [默認(rèn)值: null]
  --mandatory, -m            Specifies whether this release should be considered mandatory  [布爾] [默認(rèn)值: false]
  --noDuplicateReleaseError  When this flag is set, releasing a package that is identical to the latest release will produce a warning instead of an error  [布爾] [默認(rèn)值: false]
  --plistFile, -p            Path to the plist file which specifies the binary version you want to target this release at (iOS only).  [默認(rèn)值: null]
  --plistFilePrefix, --pre   Prefix to append to the file name when attempting to find your app's Info.plist file (iOS only).  [默認(rèn)值: null]
  --rollout, -r              Percentage of users this release should be immediately available to  [字符串] [默認(rèn)值: "100%"]
  --privateKeyPath, -k       Specifies the location of a RSA private key to sign the release with  [字符串] [默認(rèn)值: false]
  --sourcemapOutput, -s      Path to where the sourcemap for the resulting bundle should be written. If omitted, a sourcemap will not be generated.  [字符串] [默認(rèn)值: null]
  --targetBinaryVersion, -t  Semver expression that specifies the binary app version(s) this release is targeting (e.g. 1.1.0, ~1.2.3). If omitted, the release will target the exact version specified in the "Info.plist" (iOS), "build.gradle" (Android) or "Package.appxmanifest" (Windows) files.  [字符串] [默認(rèn)值: null]
  --outputDir, -o            Path to where the bundle and sourcemap should be written. If omitted, a bundle and sourcemap will not be written.  [字符串] [默認(rèn)值: null]
  --config, -c               Path to the React Native CLI configuration file  [字符串] [默認(rèn)值: null]
  -v, --version              顯示版本號  [布爾]

常用部署命令如下:

Usage: code-push deployment <command>
命令:
  add      在已存在的App中創(chuàng)建一個部署
  clear    清除與部署相關(guān)的發(fā)布歷史記錄
  remove   在App中刪除一個部署
  rm       在App中刪除一個部署
  rename   重命名一個已存在的部署
  list     列出App中的所有部署
  ls       列出App中的所有部署
  history  列出一個部署的發(fā)布歷史記錄
  h        列出一個部署的發(fā)布歷史記錄
  

至此靶剑,一個完整的發(fā)布蜻拨,檢查,安裝流程已經(jīng)基本描述完了桩引。調(diào)用RN上的熱更新代碼應(yīng)該就能收到更新提醒缎讼。

參考資料

React Native CodePush實踐小結(jié)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市坑匠,隨后出現(xiàn)的幾起案子血崭,更是在濱河造成了極大的恐慌,老刑警劉巖厘灼,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件夹纫,死亡現(xiàn)場離奇詭異,居然都是意外死亡手幢,警方通過查閱死者的電腦和手機捷凄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來围来,“玉大人跺涤,你說我怎么就攤上這事匈睁。” “怎么了桶错?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵航唆,是天一觀的道長。 經(jīng)常有香客問我院刁,道長糯钙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任退腥,我火速辦了婚禮任岸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘狡刘。我一直安慰自己享潜,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布嗅蔬。 她就那樣靜靜地躺著剑按,像睡著了一般。 火紅的嫁衣襯著肌膚如雪澜术。 梳的紋絲不亂的頭發(fā)上艺蝴,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天,我揣著相機與錄音鸟废,去河邊找鬼猜敢。 笑死,一個胖子當(dāng)著我的面吹牛盒延,可吹牛的內(nèi)容都是我干的锣枝。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼兰英,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了供鸠?” 一聲冷哼從身側(cè)響起畦贸,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎楞捂,沒想到半個月后薄坏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡寨闹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年胶坠,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片繁堡。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡沈善,死狀恐怖乡数,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情闻牡,我是刑警寧澤净赴,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站罩润,受9級特大地震影響玖翅,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜割以,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一金度、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧严沥,春花似錦猜极、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至莱找,卻和暖如春酬姆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背奥溺。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工辞色, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人浮定。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓相满,卻偏偏與公主長得像,于是被迫代替她去往敵國和親桦卒。 傳聞我的和親對象是個殘疾皇子立美,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容