RN集成到原生应用

参考

集成到现有原生应用
将RN集成到iOS原生项目中
RN嵌入到现有iOS原生应用
将RN工程嵌入到现有iOS原生应用

说明

虽然看了ReactNative官网还有网上的这些资料,有说怎么集成,但多多少少感觉不太对,写出来也是有问题,所以在这里记录一下集成成功的步骤,减少踩坑!

步骤 (以0.48.4版本RN为例)

新建相关文件
  • 在原生项目.xcodeproj同级 mkdir RNUntils 新建RNUntils存放RN相关 
  • 在RNUntils目录下 touch package.json 新建文件
1
2
3
4
5
6
7
8
9
10
11
12
{
    "name": "RNUntils",
    "version": "0.0.1",
    "private": true,
    "scripts": {
        "start": "node node_modules/react-native/local-cli/cli.js start"
    },
    "dependencies": {
        "react": "16.0.0-alpha.12",
        "react-native": "0.48.4"
    }
}
  • 执行npm install 会自动生成node_modules
  • 在RNUntils目录下 touch index.js 新建文件

:创建一个空的index.js文件。(注意在 0.49 版本之前是 index.ios.js 文件)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    Text,
    View
} from 'react-native';
export default class DemoApp extends Component {
    render() {
        return (
                <View style={styles.container}>
                <Text style={styles.welcome}>
                Welcome to React Native!
                </Text>
                <Text style={styles.instructions}>
                To get started, edit index.ios.js
                </Text>
                <Text style={styles.instructions}>
                Press Cmd+R to reload,{'\n'}
                Cmd+D or shake for dev menu
                </Text>
                </View>
                );
    }
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
AppRegistry.registerComponent('TestReactNative', () => DemoApp);


注:此处最后一行代码中的RNHighScores是自定义的rn组件的名字,iOS原生代码调用时需要用到
  • 在RNUntils文件下 终端运行 react-native bundle --platform ios --dev false --entry-file index.ios.js --bundle-output main.jsbundle 生成的 main.jsbundle 导入到原生项目中 再运行 npm start
    • 其中 index.ios.js” 根据根目录上的index.js  (0.49版本之前是index.ios.js)
    • ios/main.jsbundle  是根据在xcodeproj同级目录下的路径
  • 编辑podfile文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    # 'node_modules'目录一般位于根目录中
    # 但是如果你的结构不同,那你就要根据实际路径修改下面的`:path`
    pod 'React', :path => ‘RNUntils/node_modules/react-native', :subspecs => [
        'Core',
        'CxxBridge', # 如果RN版本 >= 0.47则加入此行
        'DevSupport', # 如果RN版本 >= 0.43,则需要加入此行才能开启开发者菜单
        'RCTText',
        'RCTNetwork',
        'RCTWebSocket', # 调试功能需要此模块
        'RCTAnimation', # FlatList和原生动画功能需要此模块
    # 在这里继续添加你所需要的其他RN模块
    ]
    # 如果RN版本 >= 0.42.0,则加入下面这行
    pod 'Yoga', :path => ‘RNUntils/node_modules/react-native/ReactCommon/yoga’
  • 执行 pod install
    :(若 0.44.3之后版本 boost pod不下来 解决方案) 貌似换了 更不行 可能和网有关 可以试试! (更换后 需要先删除pod缓存  ~/Library/Caches/Cocoapods  再pod repo update 再 pod install才可以)

原生调用
  • 需要先导入 <React/RCTRootView.h>、<React/RCTBundleURLProvider.h>

  • 调用代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    	    NSURL *jsCodeLocation = 
    [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" 
                                                   fallbackResource:nil];
        RCTRootView *rootView =
        [[RCTRootView alloc] initWithBundleURL : jsCodeLocation
                             moduleName        : @"TestReactNative"
                             initialProperties :nil
                              launchOptions    : nil];
        UIViewController *vc = [[UIViewController alloc] init];
        vc.view = rootView;
        [self presentViewController:vc animated:YES completion:nil];
    • 其中 @”index” 根据根目录上的index.js  (0.49版本之前是index.ios.js)
    • @"TestReactNative" 是js文件中最后写的名称
  • 需要修改info.plist文件


补充

以上是 在原生项目.xcodeproj同级 新建RNUntils文件存放RN相关 的操作流程
以下是 新建RNUntils文件存放RN相关、新建子文件ios 存放原生项目 的操作流程


区别在步骤 1、5、6上
1、新建文件夹专门放RN相关文件如RNUntils  新建子文件夹ios 将原生项目.xcodeproj同级所有文件复制到ios目录下
5、终端运行 修改 main.jsbundle 为 ios/main.jsbundle
6、在 podfile 文件 修改 :path => 'RNUntils/node_modules/react-native 为 :path => '../node_modules/react-native