美文网首页React Native开发React Native开发经验集
react-native与ios原生通信之iOS调用RN两种方法

react-native与ios原生通信之iOS调用RN两种方法

作者: 我属貔貅的 | 来源:发表于2019-06-21 15:39 被阅读23次

开发react-native与iOS时回用到两端通信的情况,今天说下iOS调用RN的两种写法

一:自己不实例化RCTEventEmitter子类,在iOS中用发送通知方法进行调用

二:自己实例化RCTEventEmitter子类,进行添加JS回调

一:自己不实例化RCTEventEmitter子类,在iOS中用发送通知方法进行调用

1、建立RNBridgeModule类继承与RCTEventEmitter,遵守RCTBridgeModule协议

RNBridgeModule.h文件如下


#import  <Foundation/Foundation.h>

#import <React/RCTBridgeModule.h>

#import <UIKit/UIKit.h>

#import <React/RCTEventEmitter.h>

NS_ASSUME_NONNULL_BEGIN

@interface RNBridgeModule : RCTEventEmitter <RCTBridgeModule>

@end

NS_ASSUME_NONNULL_END

2、RNBridgeModule.m文件先实现父类的supportedEvents方法


-(NSArray*)supportedEvents {

    return@[eventName1,eventName2];

}

3、实现父类的startObserving方法,里面通知的添加


- (void)startObserving {

    [[NSNotificationCenter defaultCenter] addObserver:self

                                             selector:@selector(CollectionProductSuccessForRNAction:)

                                                 name:@"notificationName1"

                                               object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self

                                             selector:@selector(CollectionProductSuccessForRNAction:)

                                                 name:@"notificationName2"

                                               object:nil];

}

4、实现通知的回调方法CollectionProductSuccessForRNAction


- (void)CollectionProductSuccessForRNAction:(NSNotification*)notification {

    dispatch_async(dispatch_get_main_queue(), ^{

        if ([notification.name isEqualToString:@"notificationName1"]) {

            [self sendEventWithName:@"eventName1" body:nil];

        }else if ([notification.name isEqualToString:@"notificationName2"]) {

            [self sendEventWithName:@"eventName2" body:nil];

        }

    });

}

5、实现父类的stopObserving移除通知


- (void)stopObserving {

    [[NSNotificationCenter defaultCenter]removeObserver:self name:@"notificationName1"object:nil];

    [[NSNotificationCenter defaultCenter]removeObserver:self name:@"notificationName2"object:nil];

}

6、在需要执行RN代码的地方发送通知就可以了


    [[NSNotificationCenter defaultCenter]postNotificationName:@"notificationName1" object:nil];

7、用通知发送不用自己实例化RNBridgeModule类了,在加载RN时回自动实例化,并且RNBridgeModule的父类RCTEventEmitter并没有把实例化方法放出来


+ (void)initialize

{

  if (self != [RCTEventEmitter class]) {

    RCTAssert(RCTClassOverridesInstanceMethod(self,@selector(supportedEvents)),

              @"You must override the `supportedEvents` method of %@", self);

  }

}

initiali方法回加载支持的方法evenName,如果自己实例化RNBridgeModule类,需要把rootView的bridge传过来才可以获取到支持的eventName,这里就设涉及到第二种方法了
8、相对应的RN中的JS代码
创建EventManager.js

import React, {
    NativeModules,
    Platform,
    NativeEventEmitter,
    DeviceEventEmitter
}from 'react-native';

var NativeModulesByIOS = NativeModules.MJRNBridgeModule;

const NativeNotificationMoudule = new NativeEventEmitter(NativeModulesByIOS)

export default class EventManager{
    subscription = null; //监听者

    /**
     * @param eventType  监听的名称,用来区分监听,String类型
     * @param callback      监听的回调,需要监听的方法
     */
    init = (eventType,callback) =>{
        if (Platform.OS === 'ios') {
            subscription = NativeNotificationMoudule.addListener(
                eventType,
                (reminder) => {
                    callback();  
                }
            );
        } else {
            subscription = DeviceEventEmitter.addListener(eventType,() => {
                callback();
            });
        }
    }

    /**
     * 销毁监听
     */
    destroy=()=>{
        if (this.subscription != null) {
                subscription.remove();
        }
    }
}

在相应的组件内实例化EventManager,并添加监听

componentDidMount() {
         this.eventManager = new EventManager();//创建
         this.eventManager.init('RefreshCreditCardPage', this._onHeaderRefresh);//注册事件

    }

二、自己实例化RCTEventEmitter子类,进行添加JS回调

1、建立RNBridgeModule类继承与RCTEventEmitter,遵守RCTBridgeModule协议

RNBridgeModule.h如下


#import

#import

#import

#import

NS_ASSUME_NONNULL_BEGIN

externNSString*constrefreshLoanMarkPage;

externNSString*constrefreshCreditCardPage;

@interface RNBridgeModule : RCTEventEmitter <RCTBridgeModule>

//设置单利

+ (instancetype)shareInstance;

//调用RN的方法API

- (void)sendEventWithName:(NSString*)eventName;

@end

NS_ASSUME_NONNULL_END

2、在RNBridgeModule.m实现单例方法和其父类的supportedEvents方法


+ (instancetype)shareInstance {

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        instance = [[self alloc] init];

    });

    return instance;

}

-(NSArray*)supportedEvents {

    return@[eventName1,eventName2];

}

3、实现调用RN的方法sendEventWithName


- (void)sendEventWithName:(NSString*)eventName {

    [self.bridge enqueueJSCall:@"RCTDeviceEventEmitter" method:@"emit" args:@[eventName] completion:NULL];

}

4、在需要调用RN方法的地方获取RNBridgeModule单例,并把RNBridgeModule的bridge设置成RCTRootView的bridge,bridge在父类RCTEventEmitter里定义的


#import "RNBridgeModule.h"

#import <React/RCTRootView.h>


@property (nonatomic, strong) RCTRootView *rnView;

@property (nonatomic, strong) RNBridgeModule *bridgeToRNModule;


    self.bridgeToRNModule = [RNBridgeModule shareInstance];

    [self.bridgeToRNModule setValue:self.rnView.bridge forKey:@"bridge"];

5、调用RN接口


[self.bridgeToRNModule refreshPageWithEventName:@"eventName1"];

6、添加RN中的js代码
创建EventManager.js,这种方法添加监听只需要和Android一种即可,不用判断平台了。

import React, {
    NativeModules,
    Platform,
    NativeEventEmitter,
    DeviceEventEmitter
}from 'react-native';

var NativeModulesByIOS = NativeModules.MJRNBridgeModule;

const NativeNotificationMoudule = new NativeEventEmitter(NativeModulesByIOS)

export default class EventManager{
    subscription = null; //监听者

    /**
     * @param eventType  监听的名称,用来区分监听,String类型
     * @param callback      监听的回调,需要监听的方法
     */
    init = (eventType,callback) =>{
        
            subscription = DeviceEventEmitter.addListener(eventType,() => {
                callback();
            });
    
    }

    /**
     * 销毁监听
     */
    destroy=()=>{
        if (this.subscription != null) {
                subscription.remove();
        }
    }
}

componentDidMount() {
         this.eventManager = new EventManager();//创建
         this.eventManager.init('RefreshCreditCardPage', this._onHeaderRefresh);//注册事件

    }

这样两种实现就实现了,第二种方法就是把RCTEventEmitter扒了一层皮,直接重新实现RCTEventEmitter类。

在此谢谢大家的喜欢,谢谢支持。

相关文章

网友评论

    本文标题:react-native与ios原生通信之iOS调用RN两种方法

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