How can a native module callback to a JavaScript internal bridge method, then do processing in the internal method, for example parsing data into JSON, and then raise an event that the react native app receives?
For cross-platform bridge modules, I want to avoid duplicating code in both Objective C and Java. When possible, I want to write cross-platform bridge module code in JavaScript and reuse for Android and iOS.
My Current Solution:
This works.
This will result in two calls to sendEventWithName:
- sendEventWithName with the "_processResponseInJavaScriptMethod"
- forwardEventWithName to sendEventWithName to the react native app.
Question:
Is there an approach for native code to process data synchronously using a JS call, then send results immediately with sendEventWithName?
Or does every native > JS call require an async _bridge enqueueJSCall
?
File: MyNativeModule.m
// Use forwardEventWithName to forward events // processed by common cross-platform JS to the react native app RCT_EXPORT_METHOD(forwardEventWithName:(NSString*)name body:(NSString*)body) { [self sendEventWithName:name body:body]; } // 1 - react native app calls sendQueryToBluetoothDevice // 2 - device calls commandResponse when response received RCT_EXPORT_METHOD(sendQueryToBluetoothDevice:(NSString*)command { [_device sendCommand:command]; } // 1 - Receives XML response from external Bluetooth device // 2 - Sends XML to internal JS method for processing // 3 - Internal JS method uses forwardEventWithName // to send event to react native app - (void) commandResponse:(NSString *) xml { [self sendEventWithName:@"_processResponseInJavaScriptMethod" body:@{@"xml": configuration}]; }
File: index.js ( native module )
// Parse xml in common JS code for both Android and iOS native modules emitter.addListener("_processResponseInJavaScriptMethod", (e) => { const body = parseXml(e.xml); // ?? Is there a way to send event directly using JS to the react native app ?? // Hack - Call native method forwardEventWithName to sendEventWithName to react native app. /// // This makes two _bridge enqueueJSCall's // 1 - One call to sendEventWithName "_myNativeModuleInternalMethod" // 2 - Second call to sendEventWithName "myNativeModuleEvent MyNativeModule.forwardEventWithName( 'myNativeModuleEventResponseReceived', JSON.stringify(body)); } })
I would recommend doing some reading on the Batched Bridge in React Native.
Native -> JS
Essentially what you can do is define a module with static methods on the JS side which you would then register with the
BatchedBridge
(registerCallableModule
) - this then enables you to directly call this method from the native side viaRCTBridge().enqueueJSCall
, where you would provide themoduleDotMethod
that corresponds to your module and function respectively; you would also pass a unique (or incremental) identifier that you would later use to map the response to each request.JS -> Native
Next you would create a Native Module that would be called on the JS side to send data back to native, passing the response data and identifier which you would then handle on the native side.
I've worked on projects where the entire service layer is on the JS side and have used this approach successfully.
Not sure what you mean by
Internal bridge module Java Script method
, but JS code can pass data to native via methods, and native can return data to JS via callbacks or promises. Native code can also send events to JS.Refer the native module documentation for more details: - https://facebook.github.io/react-native/docs/native-modules-ios.html - https://facebook.github.io/react-native/docs/native-modules-android.html