How to write react native "native module" ( bridge ) that reuses common JavaScript code?

Viewed 2294

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:

  1. sendEventWithName with the "_processResponseInJavaScriptMethod"
  2. 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));
  }
})
2 Answers
Related