React Native 集成到iOS原有的项目上

news2024/12/23 14:24:04

1.官方说明地址:

集成到现有原生应用

2. 主要步骤说明

把 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 服务,运行应用。 验证这部分组件是否正常工作。

3. 开发环境准备

如果还没有搭建React Native的环境,就查看官方文档的步骤,进行安装。
如果已经安装,就请忽略这个步骤。

4. 步骤详细说明

4.1 配置项目目录结构

首先创建一个空目录用于存放 React Native 项目,然后在其中创建一个/ios子目录,把你现有的 iOS 项目拷贝到/ios子目录中

4.2 安装 JavaScript 依赖包

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

{
  "name": "ReactToIOS",  // 你项目的名字
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint ."
  },
  "dependencies": {
    "react": "17.0.2",
    "react-native": "0.68.2"
  },
  "devDependencies": {
    "@babel/core": "^7.22.5",
    "@babel/runtime": "^7.22.5",
    "@react-native-community/eslint-config": "^3.2.0",
    "babel-jest": "^29.5.0",
    "eslint": "^8.43.0",
    "jest": "^29.5.0",
    "metro-react-native-babel-preset": "^0.76.7",
    "react-test-renderer": "17.0.2"
  },
  "jest": {
    "preset": "react-native"
  }
}

打开一个终端/命令提示行,进入到项目目录中(即包含有 package.json 文件的目录),然后运行下列命令来安装:

  1. 执行安装ReactNative命令行工具
    npm install -g react-native-cli
  2. 执行安装 React 和 React Native 模块
    yarn add react-native

需要注意的是,官方有个提示了一个注意事项,如下:
在这里插入图片描述

4.3 配置 CocoaPods 的依赖

  1. 创建Podfile的最简单的方式就是在/ios子目录中使用 CocoaPods 的init命令:
    pod init
  2. 配置Podfile文件
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

platform :ios, '13.0'
install! 'cocoapods', :deterministic_uuids => false

# test 需要替换成你自己的工程名字
target 'test' do  
  config = use_native_modules!

  # Flags change depending on the env values.
  flags = get_default_flags()

  use_react_native!(
    :path => config[:reactNativePath],
    # to enable hermes on iOS, change `false` to `true` and then install pods
    :hermes_enabled => flags[:hermes_enabled],
    :fabric_enabled => flags[:fabric_enabled],
    # An absolute path to your application root.
    :app_path => "#{Pod::Config.instance.installation_root}/.."
  )

  # Pods for test

  # testTests 需要替换成你自己的工程Tests名字
  target 'testTests' do
    inherit! :complete
    # Pods for testing
  end

  use_flipper!()

  post_install do |installer|
    react_native_post_install(installer)
    __apply_Xcode_12_5_M1_post_install_workaround(installer)
  end

end

  1. 安装 React Native 的 pod 包
    pod install
    然后你应该可以看到类似下面的输出表示安装成功 (译注:同样由于众所周知的网络原因,pod install 的过程在国内非常不顺利,请自行配备稳定的代理软件。)
Analyzing dependencies
Fetching podspec for `React` from `../node_modules/react-native`
Downloading dependencies
Installing React (0.62.0)
Generating Pods project
Integrating client project
Sending stats
Pod installation complete! There are 3 dependencies from the Podfile and 1 total pod installed.

4.4 代码集成

4.4.1 创建一个 index.js 文件

首先在项目根目录下创建一个空的index.js文件。
index.js是 React Native 应用在 iOS 上的入口文件。而且它是不可或缺的!它可以是个很简单的文件,简单到可以只包含一行require/import导入语句。本教程中为了简单示范,把全部的代码都写到了index.js里(当然实际开发中我们并不推荐这样做)。

4.4.2 在index.js中添加你自己的 React Native 代码

在index.js中添加你自己的组件。这里我们只是简单的添加一个 组件,然后用一个带有样式的组件把它包起来。

import React from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Button,
  NativeModules
} from 'react-native';

class RNHighScores extends React.Component {
  render() {
    var contents = this.props['scores'].map((score) => (
      <Text key={score.name}>
        {score.name}:{score.value}
        {'\n'}
      </Text>
    ));
    return (
      <View style={styles.container}>
        <Text style={styles.highScoresTitle}>
          珠珠测试IOS调用reactView的视图
        </Text>
        <Text style={styles.scores}>{contents}</Text>
        <Button
          onPress={() => {
            const CalendarManager = NativeModules.CalendarManager;
            CalendarManager.addEvent(
             'Birthday Party',
              '4 Privet Drive, Surrey'
          );
          }}
         title="点我返回,并调用oc的方法!"
       />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#FFFFFF'
  },
  highScoresTitle: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10
  },
  scores: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5
  }
});

// Module name
AppRegistry.registerComponent('RNHighScores', () => RNHighScores);

4.4.3 在iOS项目添加交互的代码

现在我们将从菜单链接中添加一个事件处理程序。一个方法将被添加到你的应用程序的主ViewController中。这就是RCTRootView发挥作用的地方。

  1. 在ViewController中导入RCTRootView的头文件
    #import <React/RCTRootView.h>
  2. 在 ViewController 添加交互代码
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
#import <react/RCTRootView.h>

@interface ViewController () 

@property (nonatomic, strong) UIButton *playButton; //播放按钮
@property (nonatomic, strong) UIViewController *reactVC;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.playButton = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 200, 56)];
    [self.playButton setBackgroundColor:[UIColor blueColor]];
    [self.playButton setTitle:@"点击展示reactview" forState:UIControlStateNormal];
    [self.playButton addTarget:self action:@selector(showReactView) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:self.playButton];
    
    [self addNotification];

}

// iOS 调研react的页面
- (void)showReactView {
    NSLog(@"High Score Button Pressed");
    NSURL *jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.bundle?platform=ios"];
    
    NSDictionary *dic =  @{
        @"scores" : @[
          @{
            @"name" : @"zhuzhu",
            @"value": @"1"
           },
          @{
            @"name" : @"muyu",
            @"value": @"2"
          }
        ]
    };

    RCTRootView *rootView =  [[RCTRootView alloc] initWithBundleURL: jsCodeLocation
                                                         moduleName: @"RNHighScores"
                                                  initialProperties:dic
                                                      launchOptions: nil];
    self.reactVC = [[UIViewController alloc] init];
    self.reactVC.view = rootView;
    [self.navigationController pushViewController:self.reactVC animated:YES];
}

- (void)addNotification {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(calendarNotification:) name:@"calendarNotification" object:nil];
}

// react 调用 iOS的方法
- (void)calendarNotification:(NSNotification *)noti {
    [self.navigationController popViewControllerAnimated:YES];

    NSString *message = [NSString stringWithFormat:@"rn调用oc的弹框, 内容是: name:%@, location = %@", noti.object[@"name"], noti.object[@"location"]];
    UIAlertController *alertControl = [UIAlertController alertControllerWithTitle:@"交互" message:message preferredStyle:UIAlertControllerStyleAlert];

    UIAlertAction * cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
    [alertControl addAction:cancelAction];
    
    [self presentViewController:alertControl animated:YES completion:nil];
}

上述的代码中,还需要在iOS项目中,添加一个CalendarManager(可以随便取名字)类:

---------------------------------.h

#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>

NS_ASSUME_NONNULL_BEGIN

@interface CalendarManager : NSObject <RCTBridgeModule>

@end


---------------------------------.m

#import "CalendarManager.h"
#import <React/RCTLog.h>

@implementation CalendarManager

// To export a module named CalendarManager
RCT_EXPORT_MODULE();

RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location)
{
  RCTLogInfo(@"Pretending to create an event %@ at %@", name, location);

    dispatch_async(dispatch_get_main_queue(), ^{
        NSDictionary *dic = @{@"name":name, @"location":location};
        [[NSNotificationCenter defaultCenter] postNotificationName:@"calendarNotification" object:dic];
    });
   
}

@end

4.4 设置info.plist, 添加 App Transport Security 例外

Apple 现在默认会阻止读取不安全的 HTTP 链接。所以我们需要把本地运行的 Metro 服务添加到Info.plist的例外中,以便能正常访问 Metro 服务:

<key>NSAppTransportSecurity</key>
<dict>
	<key>NSAllowsArbitraryLoads</key>
	<true/>
	<key>NSExceptionDomains</key>
	<dict>
		<key>localhost</key>
		<dict>
			<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
			<true/>
		</dict>
		<key>NSExceptionAllowsInsecureHTTPLoads</key>
		<true/>
		<key>NSIncludesSubdomains</key>
		<true/>
	</dict>
</dict>


4.5 开启服务

回到项目的根目录下,执行命令,开启服务:
yarn start

4.6 在xcode执行代码

打开xcode,如果按住 command + R 执行项目。

5. 测试过程中,遇到的问题

5.1 pod install报CocoaPods could not find compatible versions for pod "RCT-Folly

问题:RN版本升级后,pod install报CocoaPods could not find compatible versions for pod “RCT-Folly”
解决方式:pod update RCT-Folly --no-repo-update
参考文档:RN版本升级后,pod install报CocoaPods could not find compatible versions for pod “RCT-Folly”

5.2 finished with error [-1004] Error Domain=NSURLErrorDomain Code=-1004 "Could not connect to the server.”

问题:finished with error [-1004] Error Domain=NSURLErrorDomain Code=-1004 “Could not connect to the server.” UserInfo={_kCFStreamErrorCodeKey=61, NSUnderlyingError=0x600001e3c600 {Error Domain=kCFErrorDomainCFNetwork Code=-1004 “(null)” UserInfo={_NSURLErrorNW
解决方式:在info.plist 文件中添加对应的key

5.3 No metro config found in /xxx/xxx/xx.

问题:No metro config found in /Users/mac/Desktop/Learn/LearnReactive/ReactToIOS.
解决方式:在根目录下,执行安装ReactNative命令行工具
npm install -g react-native-cli

6. 最后文件的目录是这样的

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/708835.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【推式子 二项式定理】Wannafly挑战赛 B

B-求值2_Wannafly挑战赛17 (nowcoder.com) 题意&#xff1a; 思路&#xff1a; Code&#xff1a; #include <bits/stdc.h>#define int long longusing namespace std;const int mxn2e610; const int mxe2e510; const int Inf0x3f3f3f3f; const int mod998244353;int N;…

碳排放预测模型 | Python实现基于RF随机森林的碳排放预测模型

文章目录 效果一览文章概述研究内容源码设计参考资料效果一览 文章概述 碳排放预测模型 | Python实现基于RF随机森林的碳排放预测模型 研究内容 碳排放被认为是全球变暖的最主要原因之一。 该项目旨在提供各国碳排放未来趋势的概述以及未来十年的全球趋势预测。 其方法是分析这…

sql统计某一字段不同状态的数量,时间戳转日期格式、按月统计使用

背景 1、在sql语句中统计一个字段的不同状态时&#xff0c;需要将每个状态的数量查出来&#xff0c;在进行统一输出&#xff0c;涉及表多次查询&#xff0c;下面用一个聚合函数的方式进行查询&#xff0c;比较方便&#xff0c;容易理解。 2、有时候数据表中的时间字段存储的是…

谈高考志愿填报

目录 不如先说说我自己。 一、选专业还是选学校&#xff1a; 二、你想推荐/避雷的专业&#xff1a; 三、填报志愿的策略&#xff1a; 四、影响专业选择的因素&#xff1a; 各省高考成绩已出&#xff0c;又到一年高考季。张雪峰提到&#xff1a;“普通家庭不要光谈理想&…

OpenCV实战(27)——追踪视频中的特征点

OpenCV实战&#xff08;27&#xff09;——追踪视频中的特征点 0. 前言1. 追踪视频中的特征点2. 特征点追踪原理3. 完整代码小结系列链接 0. 前言 我们已经知道可以通过一些最独特的点来分析图像&#xff0c;对于图像序列同样如此&#xff0c;其中一些特征点的运动可用于了解捕…

机器视觉之表面缺陷检测

曾有一个科研项目&#xff0c;青岛啤酒厂委托&#xff0c;研究啤酒瓶的质量检测。 一般这种玻璃瓶会有一定次品、不良品&#xff0c;特征是&#xff0c;内部细细的裂缝纹路长度长于一定限制&#xff0c;那么这种啤酒瓶在运输或者开瓶盖的过程中就有炸裂的风险。 所以&#xf…

【实证分析】地区竞争、推广数字普惠金融与绿色经济效率

研究内容 基于考虑非期望产出的 Super-SBM 模型测算了 2011—2018 年中国 265 个地级市的绿色经济效率,综合运用面板模型、空间杜宾模型,系统分析了地区竞争下推广数字普惠金融对绿色经济效率的影响效应。研究发现:(1)绿色经济效率存在显著正向空间溢出效应,地理距离与经济差异…

mysql数据(添加,修改,删除,单表查询)操作

插入&#xff1a; 主键自增&#xff08;第一列&#xff09;&#xff0c;可以写null&#xff0c;自动生成 最后一列是空值null&#xff0c;即不给分配 如果设置了默认值&#xff0c;如性别设置了默认值男&#xff0c;就可以写default 1、 查询起别名&#xff0c;如果别名有特…

操作数据库DDL、DML

DDL 1、创建表 create table tb_user(id int,username varchar(20),password varchar(10) ) 2、数据类型 3、删除表 drop table 表名 4、修改表 修改表名 alter table 表名 rename to 新表名 添加一列 alter table 表名 add 列名 数据类型修改数据类型 …

Vue中watch与computed区别

<body><div id"root">姓&#xff1a;<input type"text" v-model"firstName"><br/><br/>名&#xff1a;<input type"text" v-model"lastName"><br/><br/>全名&#xff1a;&…

virtio-net前端-virtqueue

文章目录 1.概述2.数据结构3. 流程分析3.1 virtio总线创建3.3virtio-net3.3.1virtio-net初始化![在这里插入图片描述](https://img-blog.csdnimg.cn/7246c1705ac24f88b75fad63f8941ca5.png)3.3.2 virtio-net驱动发送3.3.3 Qemu virtio-net设备接收 4.virtqueue4.1数据结构4.2发…

模糊测试Fuzzing基础知识学习笔记

概念 模糊测试&#xff08;Fuzzing&#xff09;&#xff0c;是一种通过向目标系统提供非预期的输入并监视异常结果来发现软件漏洞的方法。在模糊测试中&#xff0c;用随机坏数据&#xff08;也称做 fuzz&#xff09;攻击一个程序&#xff0c;然后观察哪里遭到了破坏。 模糊测试…

6.Mysql自连接

针对相同的表进行的连接被称为“自连接”&#xff08;self join&#xff09; 那么为什么要把相同的一张表连接起来呢&#xff1f;一开始还是挺难理解的。把它想象成连接两张不同的表&#xff0c;这样容易理解一些。事实上&#xff0c;自连接还是有很多用处的 1. 在同一张表内进…

模板初识与STL简介

初识模板 引言函数模板定义实例化隐式实例化显式实例化 类模板定义实例化 STL简介STL六大组件 总结 引言 模板是泛型编程的基础 在之前我们介绍过函数重载&#xff0c;可以定义许多函数名相同参数列表不同的重载函数&#xff0c;来实现不同类型的相似操作。调用重载函数时会根…

chatgpt赋能python:归一化在PyTorch中的运用

归一化在PyTorch中的运用 PyTorch是一种广泛使用的深度学习框架&#xff0c;它可以用于训练和预测各种类型的神经网络。在深度学习中&#xff0c;归一化是提高模型性能的一种常用技术。归一化是指将输入数据进行标准化或规范化处理&#xff0c;以确保数据的统一性和一致性。在…

golang硬核技术(二)go程序从启动到运行到底经历了啥

前言 go相对其他语言&#xff0c;对并发的支持更友好。这使得他的设计和其他程序迥然不同。让我们来看看它都是如何初始化程序的&#xff0c;从程序加载到运行到底经历的什么。 我们继续之前的版本1.18.4 汇编入口 首先我们编译一个hello world 程序。 package main impor…

python--连接oracle数据库

python--连接oracle数据库 前言一、安装cx_Oracle二、导入库三、数据库操作实例3.1 连接3.2数据库查询3.3数据库插入3.4 实例从某网站上面爬取彩票号码 四、异常4.1、运行时&#xff0c;出现连接数据库失败:DatabaseError:DPI-1047解决连接失败问题1、查看Oracle的版本号2、进入…

辅助驾驶功能开发-功能规范篇(21)-1-XP行泊一体方案功能规范

XPilot Safety 主动安全系统 一、前向碰撞预防(Forward Collision Prevention) - 产品定义 基于车辆前向视觉模块和前毫米波雷达的感知能力,对车辆前方扇形区域内的车辆和VRU(弱势道路使用者) 有可能与本车的运行路线发生碰撞,进行预警、碰撞伤害降低或碰撞避免的一系列…

QT 简易视频播放器版本1.1

设计Qt界面实现播放、暂停、停止、下一集、上一集、快进、后退、倍速播放、进度调节&#xff0c;音量调节、视频播放列表等功能 先上演示效果&#xff1a; ui界面设计 videoplayer.h #ifndef VIDEOPLAYER_H #define VIDEOPLAYER_H#pragma execution_character_set("utf-…

深入了解Promise机制并使用JS实现一个Promise(一)

前言 关于为什么会有Promise以及Promise的一些用法和基本机制可以参考之前的文章JS中的异步与Promise使用整体来说&#xff0c;Promise可以帮助我们很好的解决异步的问题&#xff0c;号称是异步的终极解决方案。在浏览器中Promise是使用C实现的&#xff0c;今天就使用js来实现…