美文网首页ios developers
React Native集成到现有的原生项目

React Native集成到现有的原生项目

作者: 安静守护你 | 来源:发表于2018-11-09 15:38 被阅读3853次

    因为项目需求,在iOS原生项目中会嵌套几个RN界面,这就牵涉到了原生代码中嵌套RN代码的问题,至于集成步骤以及过程中遇到的坑都在下面一一列举,以帮助后来人。

    前提

    RN环境已经搭建完成,如若未完成,请移步
    React Native环境搭建

    将React Native集成到iOS应用中主要有如下几个步骤:

    1. 配置好React Native依赖和项目结构
    2. 了解你要集成的React Native组件
    3. 使用CocoaPods把这些组件以依赖的形式加入到项目中
    4. 创建js文件,编写React Native组件的js代码
    5. 在应用中添加一个RCTRootView,这个RCTRootView正是用来承载你的React Native组件的容器
    6. 启动React Native的Packager服务,运行应用
    7. 验证这部分组件是否正常工作

    1. 配置项目目录结构

    我在此也是为了更加深入的了解RN,所以在这里拿以前的小demo来做示范了。
    首先创建一个空目录用于存放React Native项目,然后在这个空目录中创建一个ios子目录,把现有的iOS项目拷贝到ios子目录中

    目录结构

    2. 安装JavaScript依赖包

    在项目根目录下创建一个名为package.json的文件,其中填入以下内容:

    {
      "name": "MyReactNativeApp",
      "version": "0.0.1",
      "private": true,
      "scripts": {
        "start": "node node_modules/react-native/local-cli/cli.js start"
      }
    }
    

    接下来使用yarn或者npm(两者都是node的包管理器)来安装React和React Native模块。
    打开终端,进入到根目录中(即package.json)文件所在目录,然后运行以下命令安装:

    yarn add react-native

    这样默认安装最新版本的React Native,命令执行完毕后可以看到输出中有两个警告信息:

    warning " > react-native@0.57.4" has unmet peer dependency "react@16.6.0-alpha.8af6728".
    warning Your current version of Yarn is out of date. The latest version is "1.12.3", while you're on "1.9.4".

    第一个警告提示还要安装指定版本的React,第二个警告说是yarn版本不是最新的
    然后执行命令安装指定版本的React

    yarn add react@16.6.0-alpha.8af6728

    注意:必须严格匹配警告信息中所列出的版本,高了或者低了都是不可以嘀!

    完成这个步骤之后可以发现我们的根目录下多了一些东西:

    根目录

    项目根目录下的node_modules目录中安装的都是JavaScript的以来模块(对于这个目录,我们的原则是不复制、不移动、不修改、不上传、随用随装)

    node_modules/目录记录到.gitignore文件中(即不上传到版本控制系统,只保留到本地)

    3. 安装CocoaPods

    CocoaPods是针对iOS和Mac开发的包管理工具。执行一下命令安装CocoaPods

    brew install cocoapods

    安装就不用过多的说了(毕竟都安装的有)

    4. 配置CocoaPods依赖

    React Native框架整体是作为node模块安装到项目中的。接下来我们就要在CocoaPods的Podfile中指定我们需要使用的subspecs

    可用的subspecs都列在node_modules/react-native/React.podspec文件中,基本上都是按照其功能命名的。一般来说第一个要添加的就是Core,其包含了必须的AppRegistryStyleSheetView以及其他的一些React Native核心库。如果要使用React Native的Text库(即<Text>组件),那就需要添加TCTTextsubspec,等等。

    我们需要在Podfile文件中指定所需要的subspec。创建Podfile的最简单方法就是在/ios目录中使用CocoaPods的init命令(如果原先项目中已经创建了Podfile文件,可以跳过此步):

    pod init

    这样Podfile就已经创建了,接下来就需要调整其内容以满足集成需求,调整后的Podfile内容类似下面的:

    # target的名字一般与你的项目名字相同
    target 'NumberTileGame' do
    
      # 'node_modules'目录一般位于根目录中
      # 但是如果你的结构不同,那你就要根据实际路径修改下面的`:path`
      pod 'React', :path => '../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 => '../node_modules/react-native/ReactCommon/yoga'
    
      # 如果RN版本 >= 0.45则加入下面三个第三方编译依赖
      pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
      pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
      pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
    
    end
    

    修改好Podfile文件后,就可以开始安装React Native的pod包了:

    pod install

    5. RN代码集成

    依赖搞好之后,就可以愉快的搞代码咯,接下来我们在根目录中创建一个名为home.js的文件(个人建议功能文件单独创建文件夹放到一块,不要都挤在根目录中),实现以下内容(这里的内容可以随便咯):

    import React, {Component} from 'react';
    import {Platform, StyleSheet, Text, View, NativeModules, NativeAppEventEmitter} from 'react-native';
    
    const instructions = Platform.select({
      ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu',
      android:
        'Double tap R on your keyboard to reload,\n' +
        'Shake or press menu button for dev menu',
    });
    
    var rn = NativeModules.HmRNViewController;
    
    type Props = {};
    
    export default class App extends Component<Props> {
      render() {
        return (
          <View style={styles.container}>
            <Text style={styles.welcome}>Welcome to React Native!</Text>
            <Text style={styles.instructions}>Hello World</Text>
            <Text style={styles.instructions}>这里是RN界面</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,
      },
    });
    

    代码码好了,接下来就是要iOS原生应用能够调用的到的这个页面,我们需要在项目根目录下创建一个空的index.js文件(入口文件建议放在根目录下)

    index.js文件是React Native应用在iOS上的入口文件,该入口文件也可以像iOS的main入口文件一样简单,在其中实现以下内容即可完成:

    import {AppRegistry} from 'react-native';
    import home from './home.js';  // 引入当前目录下的home.js文件
    
    // 注册组件
    AppRegistry.registerComponent('homePage', () => home);
    

    6. iOS代码集成

    RN代码搞定,接下来就是在iOS原生项目中对接RN了,这也是重点:

    假设当前的原生项目中A界面有一个按钮,点击之后要让跳转到RN界面,主要实现如下:
    在iOS项目中新建一个ViewController界面B,在B界面的viewDidLoad方法中实现以下代码:

    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        self.title = @"B";
        NSURL *jsCodeLocation;
        jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
        RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"homePage" initialProperties:@{@"name" : @"Max", @"value" : @"123456"} launchOptions:nil];
        // 这里如果引入的是一个页面,可以使用self.view = rootView;,也可以使用[self.view addSubview:rootView];,不过使用addSubview:方法必须要给rootView设置frame
        //如果是一个组件(如按钮、轮播图等等),则可以直接使用[self.view addSubview:rootView];将组件添加到当前view,并设置frame值:rootView.frame = CGRectMake(0, 100, 100, 100);
        self.view = rootView;
    }
    

    A界面的按钮点击事件中实现的功能就是普通的跳转到B界面,这里就略去了

    7. 运行项目

    运行项目,点击A界面的按钮,即可跳转到RN界面:

    报错咯

    别慌别慌,要稳住,不就是一个红屏嘛 哈哈哈
    出现这个红屏报错的原因在于:有没有发现运行项目少了点什么?一般情况下,RN项目运行的时候都会自动启动packager服务的,但是这里没有自动启动,至于怎么设置自动启动packager服务我暂时也不知道,但是可以手动启动的:

    打开终端,到达项目根目录下(即package.json所在目录),然后执行命令:

    npm start

    然后终端形如:

    启动packager服务

    刚刚打开的终端就用于启动packager服务了,想要运行项目要么再打开一个终端至根目录下运行react-native run-ios,要么进入ios文件夹打开Xcode运行,运行结果如下:

    运行结果

    在RN界面如果不想要原生的导航栏,可以在B界面中隐藏导航栏,总之,随便搞起来吧

    这篇文章所介绍的主要是更改目录结构,环境配置等等,具体代码部分很有限,所以源代码就不贴出来了。在后面还会陆续的贴出来我在学习RN中遇到的问题我和经验分享。

    相关文章

      网友评论

        本文标题:React Native集成到现有的原生项目

        本文链接:https://www.haomeiwen.com/subject/eltexqtx.html