How to write react native “native module” ( bridge

2019-05-29 02:17发布

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条回答
家丑人穷心不美
2楼-- · 2019-05-29 03:05

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 via RCTBridge().enqueueJSCall, where you would provide the moduleDotMethod 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.

查看更多
再贱就再见
3楼-- · 2019-05-29 03:12

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.

JS       --->     Native   // Method calls
Native   --->     JS       // Callbacks, Promises, Events

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

查看更多
登录 后发表回答