美文网首页iOS
iOS开发-与ReactNative交互时bridge is n

iOS开发-与ReactNative交互时bridge is n

作者: 张囧瑞 | 来源:发表于2018-05-29 22:48 被阅读103次

    上次说到了与RN交互时,RN引用原生UI组件时出现的坑,如果说上次的坑是因为没有仔细看官方文档导致的,这次的坑应该算是RN自己的问题了吧。

    这次的问题是当原生端主动向RN(JS)发送请求的时候,会崩溃,报错显示

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

    场景

    这次的需求是,需要RN方面开启一个NativeEventEmitter,这个东西类似于iOS中的NSNotificationCenter,用于监听通知。当原生部分需要主动跟RN进行通信的时候,就可以发出一个广播,RN方监听到这个广播之后就会做对应的事情。

    还是一样,我们从官方文档入手,官方文档中写的内容也不多,一屏就能显示全:

    example.png

    ok,我们也是一样,还是照着官方文档撸代码。

    先写一个继承于RCTEventEmitter的类,然后实现RCTBridgeModule协议。

    
    #import <React/RCTBridgeModule.h>
    
    #import <React/RCTEventEmitter.h>
    
    @interface CalendarManager : RCTEventEmitter <RCTBridgeModule>
    
    @end
    
    

    然后在实现的部分引入RCT_EXPORT_MODULE();

    这些都是常规操作。

    这个时候先跑一下试试。。。

    发现。。程序崩溃了,看一下原因,是因为没有实现supportedEvents方法。没关系,这个我们也不用惊讶,毕竟人家官方文档中都写了。那我们就补上这个代码,返回和RN同学商量好的方法名;

    
    - (NSArray<NSString *> *)supportedEvents
    
    {
    
     return @[@"EventReminder"];
    
    }
    
    

    然后尝试发送一次试试看看能不能实现。

    
    - (void)calendarEventReminderReceived:(NSNotification *)notification
    
    {
    
     NSString *eventName = notification.userInfo[@"name"];
    
     [self sendEventWithName:@"EventReminder" body:@{@"name": eventName}];
    
    }
    
    

    结果发现还是崩溃了,这时候提示崩溃的原因就是我们这篇文章的主题

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

    仔细看看这个报错的信息发现是因为这个bridge为空,然后仔细看你会发现,你写的代码和官方文档的没什么区别,只能去google或者查看RN的issue,这时候你会发现你不是一个人,有人会告诉你可以在Appdelegate.m中设置rootView的bridge,跟着老大哥的写法走一遍,发现好像确实没有崩溃,但是。。。

    但是。。

    好像RN这边根本没有办法监听到事件。

    。。。

    填坑

    所以这边到底要怎么来解决呢??

    实际上需要的写法是,这个类必须要使用单例,而且需要用比较优雅的方式实现单例,也就是说也要考虑到alloc init的同学,所以要重写allocWithZone:的方法。

    ok废话不多说,直接在.m文件中重写这个方法

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

    再运行,你就会发现世界是多么的美好。

    以上就是这个坑的解决方案,如果有大佬有更好的解决方案可以留言或者私信我。

    相关文章

      网友评论

        本文标题:iOS开发-与ReactNative交互时bridge is n

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