美文网首页
React Native - 原生数据通信(iOS端)

React Native - 原生数据通信(iOS端)

作者: BoxJing | 来源:发表于2023-06-24 17:45 被阅读0次
RN调用原生

需要原生定义个类实现<RCTBridgeModule>协议,比如

@interface BoxModule : NSObject<RCTBridgeModule>
@end

然后再m文件中实现,需要注意的是RCT_EXPORT_METHOD默认是在异步线程调用的,切记牵扯到UI操作需要回到主线程:

RCT_EXPORT_METHOD(goBack){
    //这里可以找到当前的viewController的navigationController进行pop操作
}

在RN文件中import { NativeModules, } from 'react-native';引入后,调用下面代码即可调用到原生中:

NativeModules.BoxModule.goBack();

如果我们需要在RN中从原生读取一个Token:

// 获取token
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getToken)
{
    NSString *token = [[NSUserDefaults standardUserDefaults]objectForKey:@"token"];
    return token;
}

在RN中这么调用:

NativeModules.BoxModule.getToken();
原生调用RN

新建类BoxEventManager类继承自RCTEventEmitter实现RCTBridgeModule协议:

#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>
NS_ASSUME_NONNULL_BEGIN

@interface BoxEventManager : RCTEventEmitter<RCTBridgeModule>
- (void)sendUserMap:(NSDictionary *)obj;
@end

NS_ASSUME_NONNULL_END

.m文件实现:

#import "BoxEventManager.h"
@implementation BoxEventManager
RCT_EXPORT_MODULE();
- (NSArray<NSString *> *)supportedEvents
{
  return @[@"userMap"];
}

- (void)sendUserMap:(NSDictionary *)obj
{
  [self sendEventWithName:@"userMap" body:obj];
}

+(id)allocWithZone:(NSZone *)zone {
  static BoxEventManager *sharedInstance = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    sharedInstance = [super allocWithZone:zone];
  });
  return sharedInstance;
}
@end

在RN中使用:

import { Text, View, NativeEventEmitter, NativeModules, SafeAreaView ,StatusBar} from 'react-native'
import React, { Component } from 'react'
const { BoxEventManager } = NativeModules;
const boxEmitter = new NativeEventEmitter(BoxEventManager);
export class Box extends Component {
    componentDidMount() { 
        console.log('加载了')
        boxEmitter.addListener(
          'userMap',
          (reminder) => {
            console.log('接收到信息了')
            console.log(reminder)
          }
        );
      }
      //需要销毁
    componentWillUnmount() {
        console.log('销毕了')
        const subscription = this.subscription;
        if (!subscription) return;
        subscription.remove()
    }
      
    render() {
        return (
            <>
            <StatusBar barStyle="dark-content" />
            <SafeAreaView style={{height:600,alignItems:'center',justifyContent:'center',backgroundColor:0xffffff}}>
                <View>
                    <Text style={{fontSize:200,color: 0xff0000}}>Box</Text>
                </View>
            </SafeAreaView>
            </>
        )
    }
}
export default Box

我们可以在iOS工程里didFin中加入代码:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    BoxEventManager *event = [[BoxEventManager alloc] init];
    [event sendUserMap:@{@"123":@"456"}];
  });

运行iOS工程后5秒出现打印信息,说明原生可以正常调用RN方法并传递参数了:

2023-06-25 17:37:09.399405+0800 boxRn[49176:625878] [javascript] 加载了
2023-06-25 17:37:14.111064+0800 boxRn[49176:625878] [javascript] 接收到信息了
2023-06-25 17:37:14.114189+0800 boxRn[49176:625878] [javascript] { '123': '456' }

相关文章

网友评论

      本文标题:React Native - 原生数据通信(iOS端)

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