无星的RN学习之旅(三)-bridge is not set.

96
无星灬
0.1 2017.07.24 21:32* 字数 713

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

踩坑了。。。
我相信肯定有兄弟需要从原生的OC向RN主动发起事件。而且这种场景也很多,比如集成第三方的服务,通过代理回调获取结果发送给RN等等等等。。。
我将我遇到的坑总结一下吧。
先看下官网怎么写的

官网介绍1
官网介绍2.png

1.你是不是像官网一样,先写一个继承自RCTEventEmitter的对象,什么都不写,看看能不能运行?
答案是:并不能运行=。=你必须写实现,也就是以下这个方法

//.m文件
- (NSArray<NSString *> *)supportedEvents
{
  return @[@"EventReminder"];
}

2.你在使用发送文件,也就是

[self sendEventWithName:@"消息名" body:参数];

运行这个方法的时候有没有崩溃啊=。=
崩溃的提示是不是

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

其实就是bridage为空。
这个时候你查这个报错提示是不是发现有人说在Appdelegate.m里把rootView的bridage赋给这个你创建的对象,然后你试了一下确实发出去了开始哈皮=。=

这时候你会发现一个悲伤的事实,不管你在RN里怎么写监听,你都监听不到这个事件=。=
那么正确的解法是什么呢=。=
(1)必须使用单例
(2)必须复写alloczone
其实就是加这么一段代码:

//.m文件
+(id)allocWithZone:(NSZone *)zone {
  static RNBridge *sharedInstance = nil;
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    sharedInstance = [super allocWithZone:zone];
  });
  return sharedInstance;
}

在APPdelegate中就不需要将rootView的bridge赋予原生模块了。
用self进行发送即可
RN中使用NativeEventEmitter进行监听即可。
还有问题简书私信我,一起交流解决=。=

2017-12-22更新

还是有兄弟对于iOS与RN的交互有问题,直接上代码吧。图片名会写明是在桥接类的.h还是.m文件的代码


.h.png
.m.png
.m.png
.m.png

接下来是js方面如何监听

js.png
js.png

这里要注意了,下面这幅截图中的代码,如果使用DevicceEventEmitter无法监听到的话,用我图中写的对应自己原生模块的nativeBridgeEmitter(名字自取)去监听。


js.png

理论上,只要你的RN方面的服务以及模块已经启动,那就可以顺畅的进行oc的主动通信,不然是无法通信而且会导致崩溃的。

无星的RN学习之旅(一)-环境安装以及新建项目
无星的RN学习之旅(二)-RN与原生的通信
无星的RN学习之旅(四)——通信、持久化存储、xcode打包
无星的RN学习之旅(五)-关于react-navigation多层级页面返回时,去掉逐层推出动画
无星的RN学习之旅(六)-第三方App跳转,苹果商店跳转,loading框

RN