Emitting (and listening for) events
Now that we have taking care of registering our UI component to be droppable, we now need to get the drop events into the JavaScript side of things.
Emitting events via the bridge#
In order to achieve this we will need to turn our native module into an event emitter, and we're going to be clever about this. Even though it is the native object that needs to dispatch the events, we will create a wrapper "emitter" class, to provide an abstraction layer that you can easily expand to handle more events.
Start by creating a BuildingAppsEmitter
Swift class in the root of the macOS folder.
import Foundation
class BuildingAppsEmitter {
public static var sharedInstance = BuildingAppsEmitter()
private static var emitter: BuildingAppsNative!
private init() {
}
func registerEmitter(emitter: BuildingAppsNative) {
BuildingAppsEmitter.emitter = emitter
}
func dispatch(name: String, body: Any?) {
BuildingAppsEmitter.emitter.sendEvent(withName: name, body: body)
}
// You can add more typesafety here if you want to
func dispatchFileDropped(body: Any!) {
dispatch(name: "fileDropped", body: body)
}
}
In the body of our class we start by created a sharedInstance
- this is a common macOS pattern for certain objects that require just a single instance to send/handle events. It's just a convenience object.
Afterwards, you can see it has a static emitter property. This needs to be an instance of our bridged objects, on which we will register once our native object is instantiated. It is important to know that this is more or less the standard way for Swift to handle shared instances (it might remind you of the NSUserNotificationCenter
we used in the Sending Notifications chapter).
We need to have an empty init
constructor; no need to put anything in here. We then create a function registerEmitter
to pass our instantiated bridge class which the class will use to dispatch the events. Along with it we create a dispatch
function, which is again just convenience around the emitter object for us to send events.
Finally we add one more method dispatchFileDropped
, which just wraps the dispatch function with a hardcoded name
, again syntax sugar to make our lives a bit easier, but you can add more events there, and we send a body
, which will be converted into a JavaScript object.
Turning our bridge into an event emitter#
We will start by exposing our new class to Swift via the native bridging file:
#import <React/RCTBridgeModule.h>
#import <React/RCTBridge.h>
#import <React/RCTEventDispatcher.h>
#import <React/RCTRootView.h>
#import <React/RCTUtils.h>
#import <React/RCTConvert.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTEventEmitter.h> // Add this line
Afterwards we can modify the macro generator file: instead of extending NSObject
it will now need to extend the RCTEventEmitter
class:
#import "React/RCTEventEmitter.h"
@interface RCT_EXTERN_MODULE(BuildingAppsNative, RCTEventEmitter)
This page is a preview of Building React Native Apps for Mac