野火🔥

【iOS&Android】RN学习3——集成进现有原生项目

2016/08/02 Share

在做了短暂的技术调研和分析之后,我决心将RN和现有的QDaily项目进行集成,并替换掉其中的广告效果展示页面。

本文开发环境为Mac,在React Native 版本为0.30。同时RN仅仅作为插件形势集成到原有Native工程中,因此主要还是一个Native工程而非RN工程

而且,本文的前提是你已经在本地配好了iOS开发环境或Android开发环境,也就是说,你起码已经是一个Android开发者或者iOS开发者。

一、必备的环境配置

先安装node.js,可以下载pkg包,也可以命令行安装:

brew install node

然后安装React Native的命令行工具(react-native-cli)

npm install -g react-native-cli

这样,最重要的东西就安装好了,其它东西都可以自己看个人情况酌情使用。此处出现任何问题,都可以直接官网或者stackoverflow。

二、集成进入iOS

iOS稍微复杂点,先介绍。

QDaily的iOS和Android客户端各维护自己的代码和git仓库,但React Native作为一个跨平台的解决方案,应该用单一的仓库进行一套代码统一管理。因此,我们这里采用了git仓库进行RN相关代码的管理,并用git submodule方式分别引入原工程。同时,在两个平台git仓库的根目录增加react文件夹,将所有RN的代码相关都放进去。

先截图看下iOS最后的目录结构:
1470152286.jpg

  • node_modules:react native依赖包,rn相关js和android、iOS的依赖lib都在里面。
  • package.json:当前项目的npm package的配置文件。有了它才有node_modules文件夹
  • index.ios.js:iOS平台加载的JS脚本
  • index.android.js:Android平台加载的JS脚本

1、init RN项目

在react文件夹运行React Native初始化命令react-native init [Project Name]

1
react-native init QDaily

2、原工程增加依赖

初始化完成后,打开在react/ios下面的同名工程,会看到下图的依赖proj:
1470152600.jpg

再打开原工程,新建个group,把上图的所有proj都拖进去。依赖工程完成。删掉react/ios和react/android文件夹。

然后在原工程的Build Phases界面里的Link Binary With Libraries,点击最下面的+号,吧所有libRCT开头的.a都加进去,如下图:
1470152888.jpg

3、增加头文件(h文件)

原工程的TARGETS->Build Settings->Header Search Paths中添加一条"$(SRCROOT)/react/node_modules/react-native/React",选择recursive,如下图:
1470153045.jpg

4、增加RN PreBuild shell脚本

这里就是用于模拟器下正确启动node.js服务器,真机下正确编译rn的bundle。

在TARGETS的Build Phases界面,点+号,选择New Run Script Phase添加一个脚本,并命名为Bundle React Native code and images,在内容中填入以下代码:

1
2
export NODE_BINARY=node
./react/node_modules/react-native/packager/react-native-xcode.sh

具体如下图所示:
1470153271.jpg

5、native固定代码配置指向的bundle

直接看代码:

1
2
3
4
5
6
7
8
#pragma - mark RCTBridgeDelegate
- (NSURL*) sourceURLForBridge:(RCTBridge *)bridge {
#if (TARGET_IPHONE_SIMULATOR)
return [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];
#else
return [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"main" ofType:@"jsbundle"]];
#endif
}

到此,原有iOS项目集成React Native完成。有两个简单技巧:

  1. 模拟器下cmd+r可以reload刷新
  2. 如果真机下运行,不打算调试RN,请勾选步骤4中图片里的Run script only when installing,可以避免每次都build bundle。如下图:
    1470153671.jpg

三、集成进Android现有工程

我们这里假设已经正确完成了中的iOS集成,并将其react文件夹做git仓库管理(node_modules请ignore)。

我们这里还假设你的工程只支持Android4.1及以上,因为这是RN支持的最低版本。

1、git配置

将react工程git仓库链接到Android原有工程,并作为git submodules的形式引入到原工程根目录。pull后目录结构如下:
1470154017.jpg

2、初始化react

在react文件夹下运行

1
npm insall

之后你就发现node_modules文件夹又出现了

3、gradle配置

根目录的gradle增加本地的maven依赖:

1
2
3
4
5
6
7
8
allprojects {
repositories {
...
maven {
url "$projectDir/../react/node_modules/react-native/android"
}
}
}

需要使用RN的module的gradle文件中增加对react native的依赖:

1
2
3
4
dependencies {
...
compile "com.facebook.react:react-native:0.30.0"
}

该gradle还要在android熟下增加ndk的配置:

1
2
3
4
5
6
7
8
9
android {
...
defaultConfig {
...
ndk {
abiFilters 'armeabi-v7a','armeabi','x86','mips'
}
}
}

sync一下,配置完成了。

4、运行

Android这里和iOS不一样,真机不会默认打包到APK中;而且android的模拟器是虚拟机,不能和Mac共享一个localhost,所以一般调试方法如下。

如果用server的bundle,需要手动设置server ip:

现在react文件根目录下把node的server启动:

1
react-native start
  • 模拟器下(geny motion),cmd+m调起开发菜单,选择Dev Settings-Debug server host for device,然后设置Mac的ip和端口号;
  • 同样的,真机可以通过摇一摇调起上面的开发菜单;
  • 真机下在4.4以上也可以设置反向代理,将localhost指向Mac,这样就默认可以调试了。代码如下:
1
adb reverse tcp:8081 tcp:8081

上面的设置完成后,可以选择Reload JS来请求刷新页面,相当于iOS模拟器的cmd+r

注意:上面说的那个开发菜单,facebook使用悬浮窗的形式实现的,如果你使用的奇葩国产Android系统,那很有可能被系统默认禁掉了这个权限,导致白屏,请自行在各自rom的权限管理把显示悬浮窗权限打开。

如果用使用离线bundle,需要手动打包:

下面这个是我写的QDaily的RN bundle打包脚本,可以做参考。因为一些地方定制化了我们自己的热更新方案,所以和官方的略有不同,我会在下一篇介绍QDaily的react native热更新方案中进行具体介绍。
1470155788.jpg

四、项目其它开发者

项目的其它开发者需要完成步骤一,然后在react目录下运行npm install后,就可以正常进行native或者RN开发。


参考链接

http://facebook.github.io/react-native/

React Native移植iOS原生项目-已更新版本

React-Native For Android 环境搭建及踩坑

ReactNative之原生模块开发并发布–iOS篇

React Native iOS配置教程

CATALOG
  1. 1. 一、必备的环境配置
  2. 2. 二、集成进入iOS
    1. 2.1. 1、init RN项目
    2. 2.2. 2、原工程增加依赖
    3. 2.3. 3、增加头文件(h文件)
    4. 2.4. 4、增加RN PreBuild shell脚本
    5. 2.5. 5、native固定代码配置指向的bundle
  3. 3. 三、集成进Android现有工程
    1. 3.1. 1、git配置
    2. 3.2. 2、初始化react
    3. 3.3. 3、gradle配置
    4. 3.4. 4、运行
      1. 3.4.1. 如果用server的bundle,需要手动设置server ip:
      2. 3.4.2. 如果用使用离线bundle,需要手动打包:
  4. 4. 四、项目其它开发者
    1. 4.0.1. 参考链接