iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >详解React Native与IOS端之间的交互
  • 334
分享到

详解React Native与IOS端之间的交互

2024-04-02 19:04:59 334人浏览 八月长安
摘要

目录前置准备RN 传值给 iOS方法 1 正常传值给原生方法 2 传递回调函数方法 3 获取 promise 回调方法 4 获取 promise 的同步方式ioS 传值给 RN 端初

前置准备

首先最好了解一点关于 oc 的语法知识

1.创建声明文件nativeModule.h


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

@interface nativeModule : NSObject <RCTBridgeModule>

@end

2.创建文件nativeModule.m


#import <Foundation/Foundation.h>
#import "nativeModule.h"

@interface nativeModule ()

@end

@implementation nativeModule

@end

这是添加完文件后的结构目录

关于 interface 的区别:

.h里面的@interface,它是供其它Class调用的。它的@property和functions,都能够被其它Class“看到”(public)

而.m里面的@interface,在OC里叫作Class Extension,是.h文件中@interface的补充。但是.m文件里的@interface,对外是不开放的,只在.m文件里可见(private)

因此,我们将对外开放的方法、变量放到.h文件中,而将不想要对外开放的变量放到.m文件中(.m文件的方法可以不声明,直接用)。

RN 传值给 iOS

方法 1 正常传值给原生

在 .m 文件中添加方法:


// 省略上面的代码

@implementation nativeModule

// 这句代码是必须的 用来导出 module, 这样才能在 RN 中访问 nativeModule这个 module
RCT_EXPORT_MODULE();

// 接收字符串
RCT_EXPORT_METHOD(addHelloWord:(NSString *)name location:(NSString *)location)
{
  NSLog(@"%@,%@", name, location);
}
@end

RN 代码:


import { Button, NativeModules } from 'react-native'
const { nativeModule } = NativeModules

<Button title={'传 2 个参数给 native'} onPress={() => {
    nativeModule.addHelloWord('你的名字', '位置:浙江')
}}/>

点击此按钮的作用,就是将 '你的名字', '位置:浙江' 这 2 个字符串传递到了原生端

方法 2 传递回调函数

在 .m 文件中添加:


// 只接受一个参数——传递给 javascript 回调函数的参数数组。
RCT_EXPORT_METHOD(checkIsRoot:(RCTResponseSenderBlock)callback) {
  NSArray *array = @[@"string", @"number"];
  callback(array);
}

在 RN 中添加代码:


<Button title={'js 传一个回调给 native,回调中收到一个数组'} onPress={() => {
    nativeModule.checkIsRoot((str: string, num: string) => {
      console.log(str, num)
    })
}}/>

这是在 RN 中 给原生端传递了一个回调函数,用来解决,部分操作完成后的回调, ** 如果 callback 多次调用 RN 会报错 **

方法 3 获取 promise 回调

在 .m 文件中添加代码:


@interface nativeModule ()

@property (nonatomic) RCTPromiseResolveBlock nORMalResolve;
@property (nonatomic) RCTPromiseRejectBlock normalReject;
@property (nonatomic) NSInteger num;

@end


// 这是一个计时器
-(void)startTime: (NSArray*) data{
  NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2 repeats:YES block:^(NSTimer * _Nonnull timer) {
    
    NSArray *events =@[@"Promise ",@"test ",@" array"];
    if (events) {
      self.normalResolve(events);
      [timer invalidate];
    } else {
      [timer invalidate];
      NSError *error=[NSError errorWithDomain:@"我是回调错误信息..." code:101 userInfo:nil];
      self.normalReject(@"no_events", @"There were no events", error);
    }
  }];
  
  [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
}

// 回调给RN的参数,回调的错误信息
RCT_EXPORT_METHOD(getHBDeviceUniqueID: (RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject) {
  
  // 要执行的任务
  self.normalResolve = resolve;
  self.normalReject = reject;
  
  [self performSelectorOnMainThread:@selector(startTime:) withObject: [NSArray arrayWithObjects: @"1", @"2", nil] waitUntilDone:YES];
}

在 RN 中添加代码:


<Button title={'native传一个 promise 给 JS'} onPress={() => {
    nativeModule.getHBDeviceUniqueID().then((arr: string[]) => {
      console.log('resolve', arr)
    }).catch((err: string) => {
      console.error(err)
    })
}}/>

nativeModule.getHBDeviceUniqueID 的执行他是一个 promise,可以获取原生端的回调, 其实和方法 2 差不多

方法 4 获取 promise 的同步方式

在 .m 文件中添加:


// 这是一个计时器2
-(void)startTime2: (NSArray*) data{
  NSLog(@"data%@",data);
  
  NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
    
    NSLog(@"%d", (int)self.num);
    
    self.num = self.num + 1;
    
    NSLog(@"%d", (int)self.num);
    
    if (self.num > 4) {
      [timer invalidate];
      NSLog(@"end");
      self.normalResolve(data);
    }
    
  }];
  
  [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
}

// RCT_REMAP_METHOD 与RCT_EXPORT_METHOD相同,但是该方法是在JS线程上从JS同步调用的,可能会返回结果。
// 同步可能会有性能问题  建议除了 promise 以外都别使用
RCT_REMAP_METHOD(findEvents,
                 findEventsWithResolver:(RCTPromiseResolveBlock)resolve
                 rejecter:(RCTPromiseRejectBlock)reject)
{
  self.normalResolve = resolve;
  self.normalReject = reject;
  
  
  self.num = 0;
  
  [self performSelectorOnMainThread:@selector(startTime2:) withObject: [NSArray arrayWithObjects: @"1", @"2", nil] waitUntilDone:YES];
}

在 RN 端添加代码:


<Button title={'native传一个 promise 给 JS2'} onPress={() => {
    nativeModule.findEvents().then((arr: string[]) => {
      console.log('resolve', arr)
    }).catch((err: string) => {
      console.error(err)
    })
}}/>

方法 4 和方法 3 大体一致,但是有一点不同,就是 RCT_REMAP_METHOD 使用此方法会将代码变成同步状态

iOS 传值给 RN 端

初始的数据提供

在 appDelegate.m 文件中添加代码:


NSArray *imageList = @[@"Http://foo.com/bar1.png",
                @"http://foo.com/bar2.png"];

NSDictionary *props = @{@"images" : imageList};


RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"learn" initialProperties:props];
// 这一行代码原本就有,不同点在于 initialProperties:props

在 RN 端写入:


// 重写 APP ,  images就是 iOS 提供的数据,这里我们通过 context 来传递数据
export default class App extends React.Component<{ images: string[] }> {

  render() {
    return <NativeProps.Provider value={this.props.images}>
      <AppContainer/>
    </NativeProps.Provider>
  }
}

// 在 hooks 里简单的使用

const images = useContext(NativeProps);

<Text>这是从 native 端传来的初始数据{JSON.stringify(images)}</Text>

添加监听事件

在 .m 文件中添加代码:


// 可供监听的事件名称
- (NSArray<NSString *> *)supportedEvents
{
  return @[@"EventReminder"];
}


RCT_EXPORT_METHOD(postNotificationEvent:(NSString *)name)
{
  NSLog(@"calendarEventReminderReceived");
    [self sendEventWithName:@"EventReminder" body:@{@"name": name}];;
}

- (void)calendarEventReminderReceived:(NSNotification *)notification
{
  // 这是官网的例子
  NSLog(@"calendarEventReminderReceived");
  NSString *eventName = notification.userInfo[@"name"];
  [self sendEventWithName:@"EventReminder" body:@{@"name": eventName}];
}

RCT_EXPORT_METHOD(Send){
  NSDictionary *dict = @{@"name" : @"veuimyzi"};
  
  NSNotification *notification = [[NSNotification alloc] initWithName:@"EventReminder" object:nil userInfo:dict] ;
  
  [self calendarEventReminderReceived:notification];
}

在 RN 中添加代码:


const ManagerEmitter = new NativeEventEmitter(nativeModule)

const [msg, setMsg] = useState([])

// hooks 中的使用,类似于 componentDidMount 生命周期
useEffect(() => {
    const subscription = ManagerEmitter.addListener(
      'EventReminder',
      (reminder) => {
        setMsg(prevState => {
          return prevState.concat(reminder.name)
        })
        console.log('这是监听的EventReminder事件回复', reminder.name)
      }
    )

    return () => {
      subscription.remove()
    }
}, [])


<Button title={'js 监听事件,让 native 给 js 发通知'} onPress={() => {
    nativeModule.postNotificationEvent('test')
}}/>

<Button title={'js 监听事件,让 native 给 js 发通知 send'} onPress={() => {
    nativeModule.Send()
}}/>

{
    msg.map((item, index) => {
      return <Text key={item + index}>item:{item}</Text>
    })
}

关于 postNotificationEvent 方法是属于最简单的使用, 在原生端调用 sendEventWithName 就可以传递数据给 RN 的监听

而另一个方法 Send 和 calendarEventReminderReceived ,一个是来自于官网的实例 讲的是从 NSNotification获取数据, Send 是传递数据给 calendarEventReminderReceived

关于监听的优化, 这个官网上也有,有空可以看下,就是在 .m 文件中添加下列代码:


@implementation nativeModule
{
  bool hasListeners;
  // 一个局部变量
}

-(void)startObserving {
  hasListeners = YES;
}

-(void)stopObserving {
  hasListeners = NO;
}
// 在发送监听的添加判断,如果有监听才发送,有效减少桥接代码的调用
if (hasListeners) { 
    [self sendEventWithName:@"EventReminder" body:@{@"name": name}];;
}

总结

上述代码的库: https://GitHub.com/Grewer/learn-rn

关于原生端和 RN 端的交互基本就是这些了,当然原生端还有更多,更复杂的操作,比如进程什么的,如果想写桥接方法,这个也会碰到很多,不过掌握了上面这些,对于一些三方 SDK 的调用是够用了

以上就是详解React Native与IOS端之间的交互的详细内容,更多关于React Native与IOS端之间的交互的资料请关注编程网其它相关文章!

--结束END--

本文标题: 详解React Native与IOS端之间的交互

本文链接: https://www.lsjlt.com/news/127513.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 详解React Native与IOS端之间的交互
    目录前置准备RN 传值给 iOS方法 1 正常传值给原生方法 2 传递回调函数方法 3 获取 promise 回调方法 4 获取 promise 的同步方式iOS 传值给 RN 端初...
    99+
    2024-04-02
  • React Native与IOS端之间交互的示例分析
    这篇文章给大家分享的是有关React Native与IOS端之间交互的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前置准备首先最好了解一点关于 oc 的语法知识创建声明文件nativeModule.h#...
    99+
    2023-06-15
  • Vue(h5)与App(android,ios)端交互详解
    前言: 最近开发vue与app交互,总结了一下开发心得。我是一名Android开发者,vue开发这块也稍有涉足,在android或者IOS中展示h5可以减少工作量,也能满足用户体验性。下面主要以Android和Vue方法介绍为主。 上菜了 ...
    99+
    2023-09-17
    vue.js android ios webview 交互
  • React Native与web的基本交互方式
    本篇内容介绍了“React Native与web的基本交互方式”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成...
    99+
    2024-04-02
  • cookie保存之谜揭晓:详解浏览器与服务器之间的交互
    随着互联网的发展,我们越来越多地使用浏览器进行网页浏览、购物、登录等操作。而在这些过程中,我们时常听到一个词语——cookie。那么cookie到底是什么?它的作用又是什么?今天我们就来揭秘cookie的保存之谜,详细解析浏览器...
    99+
    2024-01-19
    浏览器 服务器 cookie
  • 详解android与服务端交互的两种方式
    做Android开发的程序员必须知道android客户端应该如何与服务端进行交互,这里主要介绍的是使用json数据进行交互。服务端从数据库查出数据并以json字符串的格式或者map集合的格式返回到客户端,客户端进行解析并输出到手机屏幕上。此...
    99+
    2023-05-31
    android 服务端 交互
  • iOS阅读器与直播的控件重叠滑动交互详解
    目录场景一场景二场景三场景一 进行一个阅读器项目的开发时,遇到了一个问题, 需要在点击绿色区域时弹出一个菜单,因此在该区域加了一个View, 然而,当在这个区域滑动时,滑动手势被绿色...
    99+
    2022-11-13
    iOS 控件重叠滑动 iOS 控件
  • 详解Python flask的前后端交互
    目录前端index.htmlscript.js后端app.py总结场景:按下按钮,将左边的下拉选框内容发送给后端,后端再将返回的结果传给前端显示。 按下按钮之前: 按下按钮之后: ...
    99+
    2024-04-02
  • React Native Modal 的封装与使用实例详解
    目录背景Android FullScreenModal 的封装使用Android 原生实现全屏 Dialog封装给 RN 进行相关的调用Android 原生部分实现JS 部分实现使用...
    99+
    2024-04-02
  • 详解c#与python的交互方式
    目录前言: 一、IronPython 二、Python打包exe调用 三、Python提供WebApi接口(推荐) 总结: 前言:  在平时工作中,需求有多种实现方式;根据不同的需...
    99+
    2024-04-02
  • python与xml数据的交互详解
    目录一 什么是XML二 XML语法规则1. xml语法规则2. xml与html的区别三 python与xml的交互1. 获取标签对内的数据2. 获取标签属性值一 什么是XML py...
    99+
    2024-04-02
  • vue与iframe之间的交互方式(一看就会)
    目录vue与iframe之间的交互子页面向父页面传值父页面向子页面传值vue与html之间iframe交互1.父级调用子级ifram中的方法2.子级iframe(html 或者vue...
    99+
    2024-04-02
  • Vue生命周期与后端交互实现流程详解
    目录表单控制购物车案例v-model进阶(了解)vue生命周期与后端交互电影案例表单控制 1.input:checkbox(单选,多选),radio(单选) 2.代码展示 <!...
    99+
    2022-11-13
    Vue生命周期 Vue后端交互
  • IOS开发自定义Button的外观和交互行为示例详解
    目录正文定制 Button 的外观使用 ButtonStyle 定制交互动画使用 PrimitiveButtonStyle 定制交互行为系统预置的 Style注意事项为按钮添加 Tr...
    99+
    2023-02-16
    IOS自定义Button外观交互 IOS Button外观交互
  • python3--对象之间的交互,类命名空间与对象、实例的命令空间
    对象之间的交互现在有个游戏人与狗,人定义一个类,狗定义一个类,如何让两个类之间互相交互起来,让这个游戏变得更加有意思,代码如下#!/usr/bin/env python # coding: utf-8 __au...
    99+
    2023-01-30
    对象 空间 实例
  • Apache和Java文件之间的实时交互,你了解吗?
    Apache和Java是两个广泛使用的技术,它们在不同的领域发挥着重要作用。在实际应用中,我们经常需要将这两个技术进行整合,以实现更强大的功能。本文将介绍如何实现Apache和Java文件之间的实时交互,并演示一些实用的代码。 一、Apa...
    99+
    2023-10-22
    文件 实时 apache
  • 详解React中组件之间通信的方式
    一、是什么 我们将组件间通信可以拆分为两个词: 组件 通信 回顾Vue系列的文章,组件是vue中最强大的功能之一,同样组件化是React的核心思想 相比vue,...
    99+
    2024-04-02
  • 详解vue组件之间相互传值的方式
    目录概述一、父组件向子组件传值二、子组件向父组件传值1.子组件绑定一个事件,通过 this.$emit() 来触发2.通过 callback 函数3. 通过 $parent / $c...
    99+
    2024-04-02
  • Python时间戳与日期格式之间相互转化的详细教程
    目录绪论一、获取当前日期,转为10位或13位时间戳二、将10位或13位时间戳转为日期格式(年-月-日 时-分-秒)总结绪论 java默认精度是毫秒级别的,生成的时间戳是13位,而py...
    99+
    2024-04-02
  • Windows、Linux 之间的 PHP 接口:一键解决跨平台交互问题?
    随着信息技术的不断发展,操作系统的种类也越来越多,其中 Windows 和 Linux 无疑是最常见的两种操作系统。在开发过程中,我们经常会遇到需要在这两种操作系统之间进行交互的情况,而 PHP 作为一门跨平台的编程语言,也经常被用来实现这...
    99+
    2023-06-17
    windows linux 接口
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作