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

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. 最后文件的目录是这样的

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

机器学习复习6

机器学习复习 1 - 在机器学习的背景下&#xff0c;什么是诊断(diagnostic)&#xff1f; A. 这指的是衡量一个学习算法在测试集(算法没有被训练过的数据)上表现如何的过程 B. 迅速尝试尽可能多的不同方法来改进算法&#xff0c;从而看看什么方法有效 C. 机器学习在医疗领域的应用…

Python 基本数据类型(五)

文章目录 每日一句正能量List&#xff08;列表&#xff09;结语 每日一句正能量 营造良好的工作和学习氛围&#xff0c;时刻牢记宗旨&#xff0c;坚定信念&#xff0c;胸怀全局&#xff0c;埋头苦干&#xff0c;对同事尊重信任谅解&#xff0c;发扬团体协作精神&#xff0c;积极…

让集合数据操控指尖舞动:迭代器和生成器的精妙之处

文章目录 &#x1f499;迭代器&#xff08;Iterator&#xff09;迭代器的特点&#xff1a;迭代器的优点&#xff1a;代码案例&#xff1a; &#x1f49a;生成器&#xff08;Generator&#xff09;生成器的特点&#xff1a;生成器的优点&#xff1a;代码案例&#xff1a; &#…

在WSL2中安装IntelliJ IDEA开发工具

一、wsl支持图形 windows安装xming https://sourceforge.net/projects/xming/ 添加白名单 查看服务器ip ifconfig 编辑配置文件(结合自己的安装目录) ‪D:\ProgramFiles\Xming\X0.hosts 启动Xlaunh wsl 配置并验证 #b编辑配置文件 vi ~/.bashrc #末尾增加配置 export DI…

二、1什么是面向对象编程?

你好&#xff0c;我是程序员雪球&#xff0c;接下来与你一起学习什么是面向对象编程。 面向对象编程是一种编程风格。它以类或对象作为组织代码的基本单元&#xff0c;并将封装&#xff0c;抽象&#xff0c;继承&#xff0c;多态四个特性&#xff0c;作为代码设计的实现基石。 …

你如何理解 JS 的继承?

在JavaScript中&#xff0c;继承是一种机制&#xff0c;允许一个对象&#xff08;子类&#xff09;从另一个对象&#xff08;父类&#xff09;继承属性和方法。这使得子类可以共享父类的功能&#xff0c;并有能∧自身定义新的功能。 JavaScript中的继承通过原型链实现。 具体来…

RabbitMQ管理界面介绍

1.管理界面概览 connections&#xff1a; 无论生产者还是消费者&#xff0c;都需要与RabbitMQ建立连接后才可以完成消息的生产和消费&#xff0c;在这里可以查看连接情况 channels&#xff1a; 通道&#xff0c;建立连接后&#xff0c;会形成通道&#xff0c;消息的投递获取依…

ChatGPT中 top_p 和 temperature 的作用机制

1. temperature 的作用机制 GPT 中的 temperature 参数调整模型输出的随机性。随机性大可以理解为多次询问的回答多样性、回答更有创意、回答更有可能没有事实依据。随机性小可以理解为多次询问更有可能遇到重复的回答、回答更接近事实&#xff08;更接近训练数据&#xff09;…

自动化测试框架[Cypress概述]

目录 前言&#xff1a; Cypress简介 Cypress原理 Cypress架构图 Cypress特性 各类自动化测试框架介绍 Selenium/WebDriver Karma Karma的工作流程 Nightwatch Protractor TestCafe Puppeteer 前言&#xff1a; Cypress是一个基于JavaScript的端到端自动化测试框架…

【SpringMVC 学习笔记】

SpringMVC 笔记记录 1. SpringMVC 简介2. 入门案例3. 基本配置3.1 xml形式配置3.2 注解形式配置 4. 请求4.1 请求参数4.1.1 普通类型传参4.1.2 实体类类型传参4.1.3 数组和集合类型传参 4.2 类型转换器4.3 请求映射 5. 响应 1. SpringMVC 简介 三层架构 2. 入门案例 3. 基本…

基于matlab使用深度学习估计身体姿势(附源码)

一、前言 此示例演示如何使用 OpenPose 算法和预训练网络估计一个或多个人的身体姿势。 身体姿势估计的目标是识别图像中人的位置及其身体部位的方向。当场景中存在多个人时&#xff0c;由于遮挡、身体接触和相似身体部位的接近&#xff0c;姿势估计可能会更加困难。 有两种…

Spring概念:容器、Ioc、DI

目录 什么是容器&#xff1f; 什么是 IoC&#xff1f; 传统程序的开发 理解 Spring IoC DI 总结 我们通常所说的 Spring 指的是 Spring Framework&#xff08;Spring 框架&#xff09;&#xff0c;它是⼀个开源框架&#xff0c;有着活跃⽽庞⼤的社区&#xff0c;这就是它…

Swin Transformer训练报错问题

1. 训练遇到报错问题 &#xff08;1&#xff09;mportError: cannot import name _pil_interp from timm.data.transforms 原因&#xff1a; timm.data.transforms里面没有_pil_interp&#xff0c;只有str_to_pil_interp、_str_to_pil_interpolation、_pil_interpolation_to_s…

【Docker】docker安装配置Jenkins

docker 安装 Jenkins #拉镜像 docker pull jenkins/jenkins#创建卷(volume) docker volume create jenkins_home#制作容器并启动 docker run -d \ -p 8080:8080 \ -p 50000:50000 \ -v jenkins_home:/var/jenkins_home \ -v /usr/lib/jvm/java-8-openjdk-amd64:/usr/local/java…

如何将window文件夹挂载到VMware系统mnt目录

背景&#xff1a;项目开发过程中&#xff0c;通常是在Windows上编码&#xff0c;有些框架和软件只能够在Linux上面执行&#xff0c;如果在 VMware中的Linux上面开发不太方便&#xff0c;因此需要在Windows上面开发好再同步到Linux上面运行。 软件&#xff1a; Samba客户端 V…

配置Jenkins的slave agent并使用它完成构建任务

上一章&#xff0c;使用单机配置并运行了一个简单的maven项目&#xff0c;并发布到了一个服务器上启动。这一章将要配置一个slave agent&#xff0c;并将上一章的job放到agent上执行。我们agent使用的是ssh的方式 前置步骤 准备两台虚拟机&#xff1a; 192.168.233.32&#…

svn commit 用法

转载   原文&#xff1a;https://blog.csdn.net/qq_39790633/article/details/103700391 使用svn进行代码的提交有两种方法&#xff1a;一种是通过TortoiseSVN客户端界面进行提交&#xff0c;另一种是通过svn commit指令提交。 方法一&#xff1a;通过TortoiseSVN客户端界面提…

STM32速成笔记—IWDG

文章目录 一、IWDG简介二、STM32的IWDG2.1 STM32的IWDG简介2.2 喂狗2.3 IWDG框图 三、IWDG配置步骤四、IWDG配置程序4.1 IWDG初始化程序4.2 喂狗 五、应用实例 一、IWDG简介 独立看门狗&#xff08;Independent Watchdog, IWDG&#xff09;&#xff0c;什么是看门狗&#xff1…

NVIDIA-Linux-x86_64-535.54.03.run cuda_12.2.0_535.54.03_linux.run下载地址

Official Drivers | NVIDIA Linux x64 (AMD64/EM64T) Display Driver | 535.54.03 | Linux 64-bit | NVIDIA 下载连接 Download NVIDIA, GeForce, Quadro, and Tesla DriversDownload drivers for NVIDIA graphics cards, video cards, GPU accelerators, and for other GeFor…

魔兽世界私人服务器怎么开

开设魔兽世界的私人服务器涉及到一系列复杂的步骤和技术要求。下面是一个大致的指南&#xff0c;以供参考&#xff1a; 1. 硬件需求&#xff1a;首先&#xff0c;你需要一台强大的服务器来承载游戏服务器。服务器的规模和配置将取决于你计划同时容纳多少玩家以及服务器的性能要…