我不能为我的生活得到一个事件,从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]
所以我可以告诉我发送了一个应用程序事件和一个带有标签blah的设备事件,我已注册用DeviceEventEmitter和NativeAppEventEmitters监听blah事件,但我没有在监听器中回调。
我究竟做错了什么??谢谢阅读!
我已经尝试调度事件,当你使用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;
}
你可以使用NativeEventEmitter
// register eventEmitter
const {NGListener} = NativeModules; // NSListener is my class
this.eventEmitter = new NativeEventEmitter(NativeModules.NGListener);
this.eventEmitter.addListener('CancelEvent', (data) => {
console.log(data);
})
在Objective C中,您可以创建
#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希望这个帮助!!
在我的例子中,我通过保持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
RNNotification * notification = [RNNotification allocWithZone:nil]; [通知sendNotificationToReactNative]我尝试了以上所有内容,但无法在我的应用中使其工作。
最后this为我工作。
#import "RNNotification.h"
@implementation RNNotification
RCT_EXPORT_MODULE();
+ (id)allocWithZone:(NSZone *)zone {
static RNNotification *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [super allocWithZone:zone];
});
return sharedInstance;
}
- (NSArray<NSString *> *)supportedEvents
{
return @[@"EventReminder"];
}
- (void)sendNotificationToReactNative
{
[self sendEventWithName:@"EventReminder" body:@{@"name": @"name"}];
}
并在启动功能时
RNNotification *notification = [RNNotification allocWithZone: nil];
[notification sendNotificationToReactNative]
你必须像这样使用你的发射器类
[[self.bridge moduleForClass:[RNNotification class]] sendNotificationToReactNative];