【问题标题】:React Native Sending Events to JavaScript in Swift在 Swift 中将本机事件发送到 JavaScript
【发布时间】:2015-10-30 11:42:40
【问题描述】:

如何在 Swift 中向 JavaScript 发送事件?

有 Objc 代码示例如何将事件发送到 JavaScript,但我需要在 swift 中做吗?

#import "RCTBridge.h"
#import "RCTEventDispatcher.h"

@implementation CalendarManager

@synthesize bridge = _bridge;

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

@end

【问题讨论】:

标签: swift react-native


【解决方案1】:

我只是想自己解决这个问题。这实际上非常容易。以下是我的做法:

EventTests.m

#import "RCTBridgeModule.h"

@interface RCT_EXTERN_MODULE(EventTests, NSObject)

RCT_EXTERN_METHOD( testEvent:(NSString *)eventName )

@end

EventTests.Swift

import UIKit

@objc( EventTests )
class EventTests: NSObject {
    // Swift doesn't have synthesize - just define the variable
    var bridge: RCTBridge!

    @objc func testEvent( eventName: String ) {
        self.bridge.eventDispatcher.sendAppEventWithName( eventName, body: "Woot!" )
    }
}

MyModule.js

var React      = require( 'react-native' );
var EventTests = require( 'NativeModules' ).EventTests;

var {
    Component,
    NativeAppEventEmitter
} = React;

var testEventName = 'test';

class MyModule extends Component {

    constructor( options ) {
        super( options );

        // Register for our test event
        NativeAppEventEmitter.addListener( testEventName, ( body ) => {
            console.log( body );
        });

        // Call objective c function, which will emit our test event
        EventTests.testEvent( testEventName );
    }
}

module.exports = MyModule;

还要确保在您的桥接头中包含一些导入:

#import "RCTBridge.h"
#import "RCTEventDispatcher.h"

【讨论】:

  • 哇,亲爱的。我必须在 Objc 中制作它并从 Swift 发送调用 Objc 代码
  • 我在其他几个 Swift 类上也有这个工作,但在我的 AppDelegate 中使用时,self.bridgenil。有什么想法吗?
  • @jamesfzhang 您是否设法修复了 AppDelegate 中的 self.bridge 为零
  • @coldbuffet 不,我没有,只是最终向另一个通过桥发送事件的 swift 类发送通知
  • 使用这个实现现在会产生一个警告说“'sendAppEventWithName(_:body:)' is deprecated: Subclass RCTEventEmitter instead”,我不确定替换是什么,但我认为是一种新的方法。
【解决方案2】:

好的,事情已经发生了变化,所以只是更新我所做的:

我有我的 swift 模块,我需要将其设为 RCTEventEmitter

import React

@objc(MyModule)
class MyModule: RCTEventEmitter {

   var hasListener: Bool = false

   override func startObserving() {
     hasListener = true
   }

   override func stopObserving() {
     hasListener = false
   }

  @objc
  func sendMyEvent() {
     if hasListener {
       self.sendEvent(withName:"MyEvent", body:["name": eventName]];
     }
  }

  @objc
  override func supportedEvents() -> [String]! {
    return ["MyEvent","MyEvent2"];
  }

}

这是我的桥接头的样子:

#import <React/RCTBridgeModule.h>
#import <React/RCTBridge.h>
#import <React/RCTEventDispatcher.h>

在 .m 文件中我将其更改为:

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

@interface RCT_EXTERN_MODULE(MyModule, RCTEventEmitter)

【讨论】:

    【解决方案3】:

    这太疯狂了。如果此事件是由 Swift 生成的,如何将任何内容作为事件传递给 Javascript?

    我在这里遇到了同样的问题:“改为子类 RCTEventEmitter” 以下不再起作用。

    self.bridge.eventDispatcher.sendAppEventWithName( eventName, body: "Woot!" )
    

    我试过了:

    var emitter: RCTEventEmitter = RCTEventEmitter()
    

    代替:

    var bridge: RCTBridge!
    

    因此:

    self.emitter.sendEvent(withName: eventName, body: "Woot!")
    

    代替

    self.bridge.eventDispatcher.sendAppEventWithName( eventName, body: "Woot!" )
    

    从坏到坏,我从警告变成了以下硬错误:

    由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“发送事件时出错:带有正文的位置:woot。桥未设置。这可能是因为您在 RCTEventEmitter 中显式合成了桥,即使它是从 RCTEventEmitter 继承的。'

    文档很差而且陈旧。看起来使用这种热垃圾的人并不多。非常沮丧。

    这是一个旧的实现,它不再有效:

    example1

    另一篇文章,不是很有用:

    example2

    非常彻底和复杂的实现,没有人知道它是否仍然有效。在我的情况下,它没有,我在上面得到同样的错误:

    example3

    然后有几种objective-c swift鸡尾酒,我这个年纪不能喝:

    example4

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多