React Native 插曲 打離線包和CodePush發(fā)布更新

用了兩天才搞定了這些瑣碎的操作钧椰,從真機(jī)調(diào)試到利用CodePush進(jìn)行熱更新。杏瞻。所刀。知道最后才發(fā)現(xiàn)一個(gè)血的教訓(xùn):即使用了CodePush,本地也必須要有一個(gè)離線包才行伐憾,即本地需要打包一個(gè)main.jsbundle放進(jìn)項(xiàng)目中勉痴,才可以成功運(yùn)行赫模。

首先树肃,講React Native的發(fā)布更新,這就涉及到React Native的熱更新主要是怎么工作的瀑罗,關(guān)鍵在于bundle的更新胸嘴。
我們先來(lái)看看ReactNative是怎么處理bundle文件(bundle文件用于資源管理)的雏掠。可以有如下兩種方式:
1劣像、app發(fā)版時(shí)乡话,將bundle文件內(nèi)置到app中,同時(shí)將圖片和js文件內(nèi)置到app中(Android和iOS處理的不同)
2凹联、app在合適的時(shí)機(jī)慧耍,加載服務(wù)端最新的bundle文件

下面一張流程圖簡(jiǎn)單介紹ReactNative的熱更新機(jī)制:
(參考自:http://blog.csdn.net/codetomylaw/article/details/52115704

ReactNative的熱更新.png

一锥惋、打離線包(打包bundle文件內(nèi)置到app中)

離線包即本地存著一個(gè)離線包,保證沒(méi)有網(wǎng)絡(luò)的時(shí)候程序不會(huì)報(bào)錯(cuò)闸婴。
1、將js代碼打包到j(luò)sbundle文件中芍躏。
在index.ios.js所在目錄下邪乍,執(zhí)行以下命令(文件名自定義,使用codepush的時(shí)候最好命名為默認(rèn)的main.jsbundle):

//  無(wú)圖片資源等
react-native bundle --entry-file index.ios.js --platform ios --bundle-output main.jsbundle

//  有圖片資源
react-native bundle --entry-file index.ios.js --platform ios --bundle-output index.ios.bundle --platform ios --dev false --assets-dest ./  

//  或者放bundle文件夾里(注意要先保證bundle文件夾存在6钥ⅰ1永恪!) 
react-native bundle –entry-file index.ios.js –bundle-output ./bundle/iosBundle/index.ios.jsbundle –platform ios –assets-dest ./bundle/iosBundle –dev false 

/*
entry-file: RN的入口文件
bundle-out: 輸出bundle文件的輸出路徑(bundle文件名和oc里面的代碼要對(duì)應(yīng))
asset-dest:輸出的asset資源目錄
*/

2否纬、添加到項(xiàng)目中吕晌。
在xcode中添加assets【必須用Create folder references的方式,添加完是藍(lán)色文件夾圖標(biāo)】和index.ios.jsbundle(或者main.jsbundle烦味、命名不同)

網(wǎng)上參考的放bundle文件夾的目錄結(jié)構(gòu)和項(xiàng)目結(jié)構(gòu)如下:


bundle文件夾的目錄結(jié)構(gòu)和項(xiàng)目結(jié)構(gòu)(自網(wǎng)上).png

參考自:https://segmentfault.com/a/1190000004189538

個(gè)人利用第一句命令創(chuàng)建的包聂使,目錄如下:


離線包目錄結(jié)構(gòu).png

3、修改AppDelegate.m文件(只使用離線包不使用熱更新的情況)

//  URLForResource根據(jù)第一步對(duì)應(yīng)的名字對(duì)應(yīng)修改
jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"index.ios" withExtension:@"jsbundle"];

4谬俄、模擬器或者真機(jī)調(diào)試都沒(méi)有問(wèn)題柏靶。

順帶列舉下ios打包可能遇到的問(wèn)題(雖然我都沒(méi)遇到哈):
1)離線包如果開啟了chrome調(diào)試,會(huì)訪問(wèn)調(diào)試服務(wù)器溃论,而且會(huì)一直loading出不來(lái)屎蜓。
2)如果bundle的名字是main.jsbundle,app會(huì)一直讀取舊的,改名就好了。钥勋。炬转。非常奇葩的問(wèn)題,我重新刪了app算灸,clean工程都沒(méi)用扼劈,就是不能用main.jsbundle這個(gè)名字。
3)必須用Create folder references【藍(lán)色文件夾圖標(biāo)】的方式引入圖片的assets菲驴,否則引用不到圖片
4)執(zhí)行bundle命令之前荐吵,要保證相關(guān)的文件夾都存在

二、使用CodePush實(shí)現(xiàn)熱更新

1. 環(huán)境準(zhǔn)備(Mac)

1)安裝Code-push cli

$ npm install -g code-push-cli

2) 注冊(cè)CodePush賬戶

$ code-push register

執(zhí)行以上命令將會(huì)自動(dòng)打開如下圖所示的注冊(cè)頁(yè)面:

注冊(cè)頁(yè)面.png

可以使用github或者M(jìn)icrosoft帳戶注冊(cè)(本文使用GitHub賬戶進(jìn)行注冊(cè)),注冊(cè)成功后將會(huì)生成如下圖所示相應(yīng)的access token:

access token.png

按照提示在終端輸入剛生成的access token(會(huì)自動(dòng)登錄):

輸入access token.png

3)添加CodePush應(yīng)用

$ code-push app add XXX      //xxx 為你要熱部署的app name

結(jié)果如下:


添加CodePush應(yīng)用.png

2. 安裝CodePush

在項(xiàng)目更目錄(或者說(shuō)package.json所在目錄)執(zhí)行以下語(yǔ)句安裝CodePush先煎,會(huì)自動(dòng)對(duì)應(yīng)修改package.json內(nèi)容贼涩。

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

效果如下:

安裝CodePush.png

3. 集成code-push 到工程文件

CodePush集成到項(xiàng)目中,一般有三種方法:
RNPM薯蝎、CocoaPods 遥倦、"Manual"

詳細(xì)可參考CodePush的Github:
https://github.com/Microsoft/react-native-code-push

下文分別對(duì)其接入方法進(jìn)行簡(jiǎn)單介紹:
個(gè)人感覺(jué)按情況分,如果是將React Native集成到原生項(xiàng)目中的項(xiàng)目占锯,因?yàn)楸旧響?yīng)該有用到cocoaPods袒哥,所以推薦使用cocoaPods接入,比較方便簡(jiǎn)單消略。
如果是純React Native項(xiàng)目统诺,則可以考慮手動(dòng)接入。

(因?yàn)槲覝y(cè)試用的是原生集成項(xiàng)目疑俭,所以就使用了cocoaPods)

方式一:cocoaPods接入

1)修改Podfile文件:(自己注意路徑哈)

pod 'CodePush', :path => './node_modules/react-native-code-push'

2)執(zhí)行命令行更新pod:

pod install 
//  或者 
pod install --verbose --no-repo-update

方式二:手動(dòng)接入

1)將react-native-code-push文件夾中 CodePush.xcodeproj 直接拉入項(xiàng)目中Libraries中

CodePush.xcodeproj 拉入項(xiàng)目.png

2)在Link Binary With Libraries中添加Libraries/CodePush.xcodeproj /Products中的libCodePush.a以及l(fā)ibz.tbd粮呢。

Link Binary With Libraries.png

3)在Build Settings的Header Search Paths那一項(xiàng)中加入(路徑要注意)

$(SRCROOT)/../node_modules/react-native-code-push

Header Search Paths.png

方式三:RNPM接入

好像是官方推薦使用最簡(jiǎn)單的方式,不過(guò)沒(méi)有試過(guò)哈
1)安裝rnpm

$ npm -g install rnpm xcode

2)使用

$ rpm link

4. 修改項(xiàng)目配置

1)在命令行下使用code-push deployment ls <AppName> --displayKeys 查出Staging的值钞艇,在info.plist文件中添加CodePushDeploymentKey并且把Staging的值填入啄寡。
2)在Info.plist中將Bundle versions string, short的值修改為1.0.0(或者其它,結(jié)構(gòu)一樣為x.x.x哩照,且和之后code push更新的版本要對(duì)應(yīng))

info.plist配置.png

5. 修改OC代碼和JS代碼

1)在加載 js bundle的類中 修改代碼

a)首先挺物,引入頭文件:

#import "CodePush.h"

b)然后修改jsCodeLocation值:

//該文章是討論在Release下進(jìn)行相關(guān)的操作,如果是debug版本加上如下代碼飘弧,系統(tǒng)在運(yùn)行時(shí)候會(huì)自動(dòng)切換识藤。
NSURL *jsCodeLocation;
    
#ifdef DEBUG
    jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
#else
    jsCodeLocation = [CodePush bundleURL];
#endif

//如果本地js離線包不是命名main.jsbundle,需要對(duì)CodePush進(jìn)行相應(yīng)設(shè)置
jsCodeLocation = [CodePush bundleURLForResource:@"index"];
2)在js文件中(該項(xiàng)目文件是index.ios.js) 修改代碼

a)引入對(duì)應(yīng)頭文件

import codePush from "react-native-code-push";

b)在componentDidMount調(diào)用sync方法,當(dāng)你的App啟動(dòng)的時(shí)候會(huì)在后臺(tái)更新

componentDidMount(){
    codePush.sync();
  }

6. 發(fā)布更新

1)發(fā)布更新 (JavaScript-only)

當(dāng)你修改js文件的時(shí)候次伶,并且想立刻發(fā)布痴昧。則僅僅需要以下的操作:

  1. 將你修改的js文件(當(dāng)前文件是index.ios.js)打包為二進(jìn)制文件,放入指定的地方(當(dāng)前位置為根目錄)冠王。
react-native bundle --platform ios --entry-file index.ios.js --bundle-output codepush.js --dev false
  1. 將二進(jìn)制文件push到staging 環(huán)境中
code-push release [--deploymentName ] [--description ]  [--mandatory]
eg:
code-push release NativeTest codepush.js 1.0.0

// 上面代碼運(yùn)行有問(wèn)題的話赶撰,試試把codepush.js后綴改成codepush.jsbundle。柱彻。好像目前版本和我上年底的要求不同了

2)發(fā)布更新 (JavaScript + images)

  1. –assets-dest 就是你放圖片的位置(當(dāng)前僅僅是做測(cè)試豪娜,實(shí)際上最好建個(gè)文件夾專門存入相關(guān)圖片)
react-native bundle --platform ios --entry-file index.ios.js --bundle-output ./main.jsbundle --assets-dest ./<img 地址>
// main.jsbundle 為自定義名字的bundle名
  1. push bundle文件
code-push <release/debug> <projectName(與注冊(cè)的app同名)><bundle文件名> <版本號(hào)>
eg:
code-push release NativeTest main.jsbundle 1.0.0

到這一步的時(shí)候,正常來(lái)說(shuō)哟楷,該配置的都配置了瘤载,試著更新一個(gè)版本push到codepush上,運(yùn)行下項(xiàng)目卖擅,就會(huì)出現(xiàn)效果鸣奔。
注意:如果出現(xiàn)找不到main.jsbundle的報(bào)錯(cuò)坟冲,很大的原因就是沒(méi)有在本地打個(gè)離線包,詳細(xì)參考這篇文章的第一部分溃蔫。(曾經(jīng)因?yàn)檫@個(gè)原因,我看著報(bào)錯(cuò)發(fā)呆了好久琳猫,上網(wǎng)也找不到任何說(shuō)法??)

Q&A

  1. CodePush更新規(guī)則


    CodePush更新規(guī)則.png
  2. 更新后都需要重啟才能看到最新的變化 再次進(jìn)入后要等一會(huì)伟叛。TODO:還要驗(yàn)證后確定穩(wěn)定時(shí)機(jī)。
  3. 查看歷史上傳過(guò)的版本:

code-push deployment history NativeTest Staging

查看歷史上傳過(guò)的版本.png

更多的CodePush相關(guān)命令推薦參考以下幾篇文章:
Code Push 熱更新使用詳細(xì)說(shuō)明和教程
app實(shí)現(xiàn)熱更新codepush
以及CodePush的Github:
https://github.com/Microsoft/react-native-code-push

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末脐嫂,一起剝皮案震驚了整個(gè)濱河市统刮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌账千,老刑警劉巖侥蒙,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異匀奏,居然都是意外死亡鞭衩,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門娃善,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)论衍,“玉大人,你說(shuō)我怎么就攤上這事聚磺∨魈ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵瘫寝,是天一觀的道長(zhǎng)蜒蕾。 經(jīng)常有香客問(wèn)我,道長(zhǎng)焕阿,這世上最難降的妖魔是什么咪啡? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮暮屡,結(jié)果婚禮上瑟匆,老公的妹妹穿的比我還像新娘。我一直安慰自己栽惶,他們只是感情好愁溜,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著外厂,像睡著了一般冕象。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上汁蝶,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天渐扮,我揣著相機(jī)與錄音论悴,去河邊找鬼。 笑死墓律,一個(gè)胖子當(dāng)著我的面吹牛膀估,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播耻讽,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼察纯,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了针肥?” 一聲冷哼從身側(cè)響起饼记,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎慰枕,沒(méi)想到半個(gè)月后具则,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡具帮,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年博肋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蜂厅。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡束昵,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出葛峻,到底是詐尸還是另有隱情锹雏,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布术奖,位于F島的核電站礁遵,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏采记。R本人自食惡果不足惜佣耐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望唧龄。 院中可真熱鬧兼砖,春花似錦、人聲如沸既棺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)丸冕。三九已至耽梅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胖烛,已是汗流浹背眼姐。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工诅迷, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人众旗。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓罢杉,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親贡歧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子滩租,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

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