[ReactNative] 打离线包 和CodePush发布更新

首先,讲React Native的发布更新,这就涉及到React Native的热更新主要是怎么工作的,关键在于bundle的更新。我们先来看看ReactNative是怎么处理bundle文件(bundle文件用于资源管理)的。可以有如下两种方式:1、app发版时,将bundle文件内置到app中,同时将图片和js文件内置到app中(Android和iOS处理的不同)2、app在合适的时机,加载服务端最新的bundle文件
下面一张流程图简单介绍ReactNative的热更新机制:(参考自:http://blog.csdn.net/codetomylaw/article/details/52115704)

ReactNative的热更新.png

一、打离线包(打包bundle文件内置到app中)
离线包即本地存着一个离线包,保证没有网络的时候程序不会报错。1、将js代码打包到jsbundle文件中。在index.ios.js所在目录下,执行以下命令(文件名自定义,使用codepush的时候最好命名为默认的main.jsbundle):
// 无图片资源等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文件夹存在!!!) 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里面的代码要对应)asset-dest:输出的asset资源目录/

2、添加到项目中。在xcode中添加assets【必须用Create folder references的方式,添加完是蓝色文件夹图标】和index.ios.jsbundle(或者main.jsbundle、命名不同)
网上参考的放bundle文件夹的目录结构和项目结构如下:

bundle文件夹的目录结构和项目结构(自网上).png

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

个人利用第一句命令创建的包,目录如下:


离线包目录结构.png

3、修改AppDelegate.m文件(只使用离线包不使用热更新的情况)
// URLForResource根据第一步对应的名字对应修改jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"index.ios" withExtension:@"jsbundle"];

4、模拟器或者真机调试都没有问题。
顺带列举下ios打包可能遇到的问题(虽然我都没遇到哈):1)离线包如果开启了chrome调试,会访问调试服务器,而且会一直loading出不来。2)如果bundle的名字是main.jsbundle,app会一直读取旧的,改名就好了。。。非常奇葩的问题,我重新删了app,clean工程都没用,就是不能用main.jsbundle这个名字。3)必须用Create folder references【蓝色文件夹图标】的方式引入图片的assets,否则引用不到图片4)执行bundle命令之前,要保证相关的文件夹都存在

二、使用CodePush实现热更新

  1. 环境准备(Mac)
    1)安装Code-push cli
    $ npm install -g code-push-cli

2) 注册CodePush账户
$ code-push register

执行以上命令将会自动打开如下图所示的注册页面:


注册页面.png

可以使用github或者Microsoft帐户注册(本文使用GitHub账户进行注册),注册成功后将会生成如下图所示相应的access token:


access token.png

按照提示在终端输入刚生成的access token(会自动登录):
[图片上传中。。。(6)]输入access token.png

3)添加CodePush应用
$ code-push app add XXX      //xxx 为你要热部署的app name

结果如下:
[图片上传中。。。(7)]添加CodePush应用.png

  1. 安装CodePush
    在项目更目录(或者说package.json所在目录)执行以下语句安装CodePush,会自动对应修改package.json内容。
    npm install --save react-native-code-push

效果如下:


安装CodePush.png

  1. 集成code-push 到工程文件
    CodePush集成到项目中,一般有三种方法:RNPM、CocoaPods 、"Manual"
    详细可参考CodePush的Github:https://github.com/Microsoft/react-native-code-push

下文分别对其接入方法进行简单介绍:个人感觉按情况分,如果是将React Native集成到原生项目中的项目,因为本身应该有用到cocoaPods,所以推荐使用cocoaPods接入,比较方便简单。如果是纯React Native项目,则可以考虑手动接入。(因为我测试用的是原生集成项目,所以就使用了cocoaPods)
方式一:cocoaPods接入
1)修改Podfile文件:(自己注意路径哈)
pod 'CodePush', :path => './node_modules/react-native-code-push'

2)执行命令行更新pod:
pod install // 或者 pod install --verbose --no-repo-update

方式二:手动接入
1)将react-native-code-push文件夹中 CodePush.xcodeproj 直接拉入项目中Libraries中


CodePush.xcodeproj 拉入项目.png

2)在Link Binary With Libraries中添加Libraries/CodePush.xcodeproj /Products中的libCodePush.a以及libz.tbd。
[图片上传中。。。(10)]Link Binary With Libraries.png

3)在Build Settings的Header Search Paths那一项中加入(路径要注意)
$(SRCROOT)/../node_modules/react-native-code-push

[图片上传中。。。(11)]Header Search Paths.png

方式三:RNPM接入
好像是官方推荐使用最简单的方式,不过没有试过哈1)安装rnpm
$ npm -g install rnpm xcode

2)使用
$ rpm link

  1. 修改项目配置
    1)在命令行下使用code-push deployment ls <AppName> --displayKeys 查出Staging的值,在info.plist文件中添加CodePushDeploymentKey并且把Staging的值填入。2)在Info.plist中将Bundle versions string, short的值修改为1.0.0(或者其它,结构一样为x.x.x,且和之后code push更新的版本要对应)
    [图片上传中。。。(12)]info.plist配置.png

  2. 修改OC代码和JS代码
    1)在加载 js bundle的类中 修改代码
    a)首先,引入头文件:

import "CodePush.h"

b)然后修改jsCodeLocation值:
//该文章是讨论在Release下进行相关的操作,如果是debug版本加上如下代码,系统在运行时候会自动切换。NSURL *jsCodeLocation;#ifdef DEBUG jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];#else jsCodeLocation = [CodePush bundleURL];#endif//如果本地js离线包不是命名main.jsbundle,需要对CodePush进行相应设置jsCodeLocation = [CodePush bundleURLForResource:@"index"];

2)在js文件中(该项目文件是index.ios.js) 修改代码
a)引入对应头文件
import codePush from "react-native-code-push";

b)在componentDidMount调用sync方法,当你的App启动的时候会在后台更新
componentDidMount(){ codePush.sync(); }

  1. 发布更新
    1)发布更新 (JavaScript-only)
    当你修改js文件的时候,并且想立刻发布。则仅仅需要以下的操作:
    将你修改的js文件(当前文件是index.ios.js)打包为二进制文件,放入指定的地方(当前位置为根目录)。react-native bundle --platform ios --entry-file index.ios.js --bundle-output codepush.js --dev false

将二进制文件push到staging 环境中code-push release [--deploymentName ] [--description ] [--mandatory]eg:code-push release NativeTest codepush.js 1.0.0

2)发布更新 (JavaScript + images)
–assets-dest 就是你放图片的位置(当前仅仅是做测试,实际上最好建个文件夹专门存入相关图片)react-native bundle --platform ios --entry-file index.ios.js --bundle-output ./main.jsbundle --assets-dest ./<img 地址>// main.jsbundle 为自定义名字的bundle名

push bundle文件code-push <release/debug> <projectName(与注册的app同名)><bundle文件名> <版本号>eg:code-push release NativeTest main.jsbundle 1.0.0

到这一步的时候,正常来说,该配置的都配置了,试着更新一个版本push到codepush上,运行下项目,就会出现效果。注意:如果出现找不到main.jsbundle的报错,很大的原因就是没有在本地打个离线包,详细参考这篇文章的第一部分。(曾经因为这个原因,我看着报错发呆了好久,上网也找不到任何说法😂)

Q&A
CodePush更新规则[图片上传中。。。(13)]CodePush更新规则.png

更新后都需要重启才能看到最新的变化 再次进入后要等一会。TODO:还要验证后确定稳定时机。
查看历史上传过的版本:code-push deployment history NativeTest Staging

[图片上传中。。。(14)]查看历史上传过的版本.png

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容