React Native 踩坑日记(十三) —— OC 往 JS 发消息

本篇针对 iOS

参考链接

官方文档,查看 Sending Events to JavaScript
的参考文章
stack overflow 原理介绍

概述

本篇主要是一个踩坑的笔记。
实际开发中,经常会需要iosrn,或者说OC/SwiftJS 之间的通信。

一个实际的应用场景描述:

我有 A,B 两个页面,A 页面是 Native, B 页面是 RN, 现在在 A 页面做了一个提交操作,提交成功后,需要跳转到 B 页面,并通知 B 页面刷新。

官方的文档描述Sending Events to JavaScript

有几个坑。如果只是简单的继承RCTEventEmitter然后写一个发送消息,通常情况下原生这边是会闪退,报:

bridge is not set. This is probably because you've " "explicitly synthesized the bridge in %@, even though it's inherited " "from RCTEventEmitter.

这里要做以下的几个说明。

说明

一个重要的原则就是:
桥接必须要把 NativeReact Native 两边都写好才可以。好比一座桥的两端,如果你只是写好一端的话,另一端路走不通,还是会报错的。

下面是参考代码

OC

.h

#import 
#import 
#import "React/RCTBridge.h"

@interface SendMessageToRN: RCTEventEmitter
- (void)needRefreshMyFeedbackList:(NSNotification *)notification;
@end

.m

#define RefreshListMsg @"RefreshListMsg" // 记住这这个,相当于广播名
@implementation SendMessageToRN
RCT_EXPORT_MODULE(RefreshMyFeedback); //这行一定要写,并且记住括号内的名称,且和 RN 中的代码保持一致
- (NSArray *)supportedEvents {
    return @[RefreshListMsg,];
}

// 可以使用这个单例来做
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    static SendMessageToRN *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [super allocWithZone:zone];
    });
    return sharedInstance;
}

- (void)needRefreshMyFeedbackList:(NSNotification *)notification {
    if (self.bridge) {// 务必加一个判断,万一 RN 那端桥接没有做好,不至于崩溃
        [self sendEventWithName:RefreshListMsg body:@{}];
    }
}

调用的时候,使用单例,然后调用代码

SendMessageToRN *sendMsg = [SendMessageToRN allocWithZone:nil];
[sendMsg needRefreshMyFeedbackList:nil];

JS 这端的代码

import {
    StyleSheet, View, Dimensions, Text, NativeEventEmitter, NativeModules
} from 'react-native';

//...省略部分代码
    componentWillMount() {
        //RefreshMyFeedback就是上面定义的 RCT_EXPORT_MODULE(RefreshMyFeedback);
        let nativeBridge = NativeModules.RefreshMyFeedback;
        let refreshEmitter = new NativeEventEmitter(nativeBridge);
        this.listener = refreshEmitter.addListener(
            'RefreshListMsg',// RefreshListMsg就是 OC 那边定义的广播名
            (reminder) => {
                console.log(reminder.name);
                this._onRefresh();
            }
        );
    }

    componentDidMount() {
        this._onRefresh();
    }

    componentWillUnmount() {
        this.listener.remove();// 用完记得销毁掉
    }

你可能感兴趣的:(React Native 踩坑日记(十三) —— OC 往 JS 发消息)