我无法为我的生活获得一个事件,以便从iOS本机跨桥传输到反应本机JS上下文。在Objective-C方面,我希望有一个模块可以轻松地在整个桥上发送事件。我已经调用了这个类EventEmitter,它的定义如下:
// EventEmitter.h
#import "RCTBridge.h"
#import "RCTEventDispatcher.h"
@interface EventEmitter : NSObject<RCTBridgeModule>
- (void)emitEvent:(NSString *) eventName withData:(id) eventData;
@end
和实施:
// EventEmitter.m
#import "EventEmitter.h"
@implementation EventEmitter
RCT_EXPORT_MODULE();
@synthesize bridge = _bridge;
- (void)emitEvent:(NSString *) eventName withData:(id) eventData
{
NSLog( @"emitting %@ with data %@", eventName, [eventData description] );
[[_bridge eventDispatcher] sendDeviceEventWithName:eventName body:eventData];
[[_bridge eventDispatcher] sendAppEventWithName:eventName body:eventData];
}
@end
我同时使用sendDeviceEvent和sendAppEvent,因为我无法工作。
在JS方面,我注册在我的一个模块的全局命名空间中接收这些事件(因此我知道事件订阅将在事件发出之前发生)。我这样注册:
console.log( 'ADDING EVENT LISTENERS' );
NativeAppEventEmitter.addListener( 'blah', test => console.log( 'TEST1', test ) );
DeviceEventEmitter.addListener( 'blah', test => console.log( 'TEST2', test ) );
在我的日志语句中,我得到以下内容:
2016-03-19 12:26:42.501 [trace][tid:com.facebook.React.JavaScript] ADDING EVENT LISTENERS
2016-03-19 12:26:43.613 [name redacted][348:38737] emitting blah with data [data redacted]
所以我可以告诉我发送了一个app事件和一个带有标签blah的设备事件,我已经注册了用DeviceEventEmitter和NativeAppEventEmitters来监听blah事件,但是我没有被回调听众。
我做错了什么?谢谢你的阅读!
答案 0 :(得分:5)
您可以使用NativeEventEmitter
// register eventEmitter
const {NGListener} = NativeModules; // NSListener is my class
this.eventEmitter = new NativeEventEmitter(NativeModules.NGListener);
this.eventEmitter.addListener('CancelEvent', (data) => {
console.log(data);
})
在ObjectiveC中,您可以创建
#import <RCTViewManager.h>
#import <RCTEventEmitter.h>
@interface NGListener: RCTEventEmitter <RCTBridgeModule>
@end
@implementation NGListener
RCT_EXPORT_MODULE();
- (NSArray<NSString*> *)supportedEvents {
return @[@"CancelEvent", @"OKEvent"];
}
// And you sent event you want from objectC to react-native
[self sendEventWithName:@"CancelEvent" body:@"Tap`enter code here` on Cancel button from Objc"];
我编写了示例示例来处理从react-native到objectivec以及相反的事件。 https://github.com/lengocgiang/event-listener 希望这有帮助!!
答案 1 :(得分:4)
我尝试过调度事件,但是当您使用bridge
EventEmitter
实例时,似乎[EventEmitter alloc] init]
未初始化
您应该让react-native创建实例。我检查了本机组件,他们使用-(void)setBridge:(RCTBridge *)bridge
方法进行初始化工作。请查看RCTLinkingManager
以查看示例。它使用NSNotificationCenter
来处理事件。
// registering for RCTOpenURLNotification evet when the module is initialised with a bridge
- (void)setBridge:(RCTBridge *)bridge
{
_bridge = bridge;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleOpenURLNotification:)
name:RCTOpenURLNotification
object:nil];
}
// emitting openURL event to javascript
- (void)handleOpenURLNotification:(NSNotification *)notification
{
[_bridge.eventDispatcher sendDeviceEventWithName:@"openURL"
body:notification.userInfo];
}
// creating RCTOpenURLNotification event to invoke handleOpenURLNotification method
+ (BOOL)application:(UIApplication *)application
openURL:(NSURL *)URL
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
NSDictionary<NSString *, id> *payload = @{@"url": URL.absoluteString};
[[NSNotificationCenter defaultCenter] postNotificationName:RCTOpenURLNotification
object:self
userInfo:payload];
return YES;
}
答案 2 :(得分:2)
在我的情况下,我通过保留RCTRootView的桥接值并将其传递给发射器实例来实现此功能。
@implementation AppDelegate {
RCTBridge *rootBridge;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *jsCodeLocation;
......
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"MyApp"
initialProperties:nil
launchOptions:launchOptions];
rootBridge = rootView.bridge;
.......
}
- (IBAction)doAction:(id)sender {
BridgeEvents *events = [[BridgeEvents alloc] init];
[events setBridge:rootBridge];
[events doMyAction];
}
在我的发射器课程中:
#import "RCTEventEmitter.h"
@interface BridgeEvents : RCTEventEmitter <RCTBridgeModule>
- (void)doMyAction;
@end
#import "BridgeEvents.h"
@implementation BridgeEvents
RCT_EXPORT_MODULE();
- (NSArray<NSString *> *)supportedEvents {
return @[@"onEvent"];
}
- (void)doMyAction {
[self sendEventWithName:@"onEvent" body:@""];
}
@end
答案 3 :(得分:0)
RNNotification * notification = [RNNotification allocWithZone:nil]; [通知sendNotificationToReactNative]我尝试了以上所有内容,但无法在我的应用中使其工作。
最后this为我工作。
RNNotification *notification = [RNNotification allocWithZone: nil];
[notification sendNotificationToReactNative]
并在启动函数时
val repeatSmokers: List[(String, String, String, String, String, String)] =
List(
("ID76182", "sachin", "kita MR.", "56308", "1990", "300"),
("ID76182", "KOUN", "Jana MR.", "56714", "1990", "100"),
("ID76182", "GANGS", "SKILL", "27539", "1990", "255"),
("ID76182", "GANGS", "SKILL", "27539", "1990", "110"),
("ID76182", "SEMI", "GAUTAM A MR.", "45873", "1990", "20"),
("ID76182", "SEMI", "GAUTAM A MR.", "45873", "1990", "6750"),
("ID76182", "DOWNES", "RYAN", "47542", "1990", "2090"),
("ID76182", "DRAGON", "WARS", "49337", "1990", "200"),
("ID76182", "HULK", "PAIN MR.", "47542", "1990", "280"),
("ID76182", "JAMES", "JIM", "30548", "1990", "300"),
("ID76182", "KIMMELSHUE", "RUTH", "55345", "1990", "2600"),
("ID76182", "DRAGON", "WARS", "49337", "1990", "370"),
("ID76182", "COOPER", "ANADA", "45873", "1990", "2600"),
("ID76182", "SEMI", "GAUTAM A MR.", "45873", "1990", "2600"),
("ID76182", "HULK", "PAIN MR.", "47542", "1990", "256")
)
答案 4 :(得分:0)
您必须像这样使用发射器类
[[self.bridge moduleForClass:[RNNotification class]] sendNotificationToReactNative];