美文网首页iOS程序猿iOS点点滴滴RN iOS开发相关
iOS原生项目集成ReactNative(持续更新)

iOS原生项目集成ReactNative(持续更新)

作者: calary | 来源:发表于2018-01-04 11:51 被阅读101次

    前言

    最近发现很多app都使用了ReactNative这门火热的技术,不禁虎躯一震,因为公司的工作相对安逸,自己一直打算学习一下,但每次都不了了之,这次又默默看了看招聘信息,RN已经势不可挡,新的一年想升职加薪看来要努力啦!
    下面进入我们的主题,在iOS原生项目中集成ReactNative,鼓捣了一天终于成功了,鉴于市面上的资料都有些老旧了,所以我将我的经验分享给大家,赶紧上车,落后就要挨打。

    tips:如果操作过程中碰到什么错误或问题,请到文章最后问题合集中查看是否有解决办法

    一、准备工作

    本文使用的版本
    "react": "16.0.0",
    "react-native": "0.51.0"

    1、搭建开发环境

    如果你已经创建过RN项目,并且运行成功了,那么你的环境配置肯定是没有问题的,但是如果你是第一次进行学习,那么就要搭建开发环境了,具体的可以参考搭建ReactNative开发环境,搭建好后你可以按照他的提示创建一个RN项目运行一下,看环境是否成功

    2、安装CocoaPods

    CocoaPods相信每一个iOS开发者都有接触吧,如果你没有使用过也没关系,参考CocoaPods的安装使用和常见问题这篇文章学习下吧。
    本文只提供CocoaPods安装React Native的方式,这个简单易用。
    这里就不提供手动集成的办法了,因为笔者也没尝试过,如果有需要可以自己查资料。

    二、集成ReactNative

    1、文件配置

    1)创建存放文件夹RNComponent和配置文件package.json

    在项目中创建文件夹RNComponent并创建package.json配置文件,文件夹名字可以自定义,主要用来存放RN相关的文件,如下图

    //package.json 终端创建方法
    $ cd 需要放置的目录下(项目的根目录/项目中自己创建的文件夹)
    $ touch package.json
    
    文件目录.png

    package.josn 中的内容如下,其中name位App的名字,dependencies为react和react-native的版本,在创建这些信息时,建议利用react-native init AwesomeProject新建新项目时会自动创建package.json,直接把文件复制过来,更改name为自己的原生项目名,确保信息为最新的,且不容易出错。

    {
      "name": "RNExample",
      "version": "0.0.1",
      "private": true,
      "scripts": {
        "start": "node node_modules/react-native/local-cli/cli.js start",
        "test": "jest"
      },
      "dependencies": {
        "react": "16.0.0",
        "react-native": "0.51.0"
      },
      "devDependencies": {
        "babel-jest": "22.0.4",
        "babel-preset-react-native": "4.0.0",
        "jest": "22.0.4",
        "react-test-renderer": "16.0.0"
      },
      "jest": {
        "preset": "react-native"
      }
    }
    
    
    2)安装React Native依赖包

    进入到RNComponent文件夹下运行命令行

    npm install
    

    执行结束后项目中会多出一个node_modules文件夹。

    执行指令.png 执行结果png

    看到有的文章说这里执行起来很慢,但是我这里很快,图中看见27.596s,可能是因为我在配置环境的时候使用了淘宝镜像,建议大家也这么做,搭建ReactNative开发环境里面有方法。

    2、创建入口文件index.ios.js

    终端创建方法

    $ cd 需要放置的目录下(项目的根目录/项目中自己创建的文件夹)
    $ touch index.ios.js
    
    image.png

    我这里开发使用的工具是WebStorm,这里可以分享下我的下载地址

    index.ios.js 代码如下

    import React, { Component } from 'react';
    import {
        AppRegistry,
        StyleSheet,
        Text,
        View
    } from 'react-native';
    
    class RNExample 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('App', () => RNExample);
    

    3. Cocoapods集成React Native

    如果还没有使用CocoaPods

    $ cd 项目的根目录
    $ touch Podfile
    $ open -e Podfile
    $ pod install //只是注释,在内容添加保存后执行
    
    image.png

    Podfile中添加的内容,添加后保存,然后执行 pod install

    source 'https://github.com/CocoaPods/Specs.git'
    platform :ios, ‘9.0’
    use_frameworks!
    
    target ‘RNExample’ do
      # 'node_modules'目录一般位于根目录中
      # 但是如果你的结构不同,那你就要根据实际路径修改下面的`:path`
      pod 'React', :path => ‘./RNComponent/node_modules/react-native', :subspecs => [
        'Core',
        'BatchedBridge', # 0.45 版本以后需要添加
        'DevSupport', # 如果RN版本 >= 0.43,则需要加入此行才能开启开发者菜单
        'RCTText',
        'RCTImage',
        'RCTNetwork',
        'RCTWebSocket', # 这个模块是用于调试功能的
        # 在这里继续添加你所需要的模块
      ]
      # 如果你的RN版本 >= 0.42.0,则加入下面这行
      pod “yoga", :path => “./RNComponent/node_modules/react-native/ReactCommon/yoga"
    
    end
    

    注:上面添加的有注释的几个都是查找多处资料找到的,好多老的资料都不可行了

    执行结果:


    image.png

    三、项目处理

    1、打开项目

    使用CocoaPods后需要用箭头所示文件打开


    image.png

    2、添加RCTRootView

    这里只是在ViewController中进行了测试,具体放在什么地方,怎么放置大家根据项目需求而定

    #import "ViewController.h"
    #import <React/RCTRootView.h>
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
        button.center = self.view.center;
        [button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
        [button setTitle:@"Hello" forState:UIControlStateNormal];
        [button addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:button];
    }
    
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    - (void)buttonAction{
        NSString * strUrl = @"http://localhost:8081/index.ios.bundle?platform=ios&dev=true";
        NSURL * jsCodeLocation = [NSURL URLWithString:strUrl];
        
        RCTRootView * rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                             moduleName:@"App"
                                                      initialProperties:nil
                                                          launchOptions:nil];
        self.view = rootView;
    }
    
    @end
    

    3、配置App Transport Security

    在iOS 9以上的系统中,除非明确指明,否则应用无法通过http协议连接到localhost主机。 建议在Info.plist进行如下设置,否则会报Could not connect to development server错误


    image.png

    4、开启服务器

    在运行我们的项目之前,我们需要先启动我们的开发服务器。进入 RNComponent目录 ,然后命令行启动服务:

    react-native start
    

    5、运行程序

    我这里是用Xcode运行的项目,指令没有运行起来,很尴尬。
    项目跑起来,very good😄,这里只是在模拟器上运行,真机上运行请见问题合集2

    image.png

    之前一直报错无法连接服务器,现在我觉得问题就是没有执行第四部开启服务器,如果有什么问题请留言交流,下面有个问题集合,我以后遇到的问题都会收集起来,希望对大家有所帮助,共同进步。

    6、吃水不忘挖井人

    参考链接:
    https://www.jianshu.com/p/3dc9d70a790f
    https://reactnative.cn/docs/0.42/getting-started.html
    https://www.jianshu.com/p/47174bf215bf

    四、问题集合

    问题都是我在开发中遇到的,情况不同解决方法可能不同仅供参考

    1、'fishhook/fishhook.h' file not found

    image.png

    解决办法:将#import <fishhook/fishhook.h> 改为 #import "fishhook.h"即可

    2、Could not connect to development server

    如果正常的话http://localhost:8081/index.ios.bundle?platform=ios&dev=true将会有内容
    解决办法:

    • 1、是否配置App Transport Security
    • 2、是否开启服务器,执行react-native start
    • 3、真机上运行报错
      如果模拟器上是可以的而在真机上运行报上面的错误请按下面步骤执行,
      打开设置-网络-查看当前ip地址,将项目中的localhost改为当前ip(注意,手机的wifi应当和电脑的wifi是同一个才可以)


      image.png

    相关文章

      网友评论

      • 醉叶惜秋:请问我该怎么在index.ios.js 文件中调用 oc 的项目啊

      本文标题:iOS原生项目集成ReactNative(持续更新)

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