如何写反应原生"原生模块" (桥)重用常见的JavaScript代码?

时间:2017-05-31 17:52:19

标签: react-native bridge

本机模块如何回调到JavaScript内部桥接方法,然后在内部方法中进行处理,例如将数据解析为JSON,然后引发react本机应用程序接收的事件?

对于跨平台网桥模块,我希望避免在 Objective C和Java中重复代码。如果可能,我想用JavaScript编写跨平台桥模块代码,并重用Android和iOS。

我当前的解决方案:

这很有效。

这将导致对sendEventWithName的两次调用:

  1. sendEventWithName with" _processResponseInJavaScriptMethod"
  2. forwardEventWithName to sendEventWithName to react native app。
  3. 问题:

    是否存在使用JS调用同步处理数据的本机代码的方法,然后使用sendEventWithName立即发送结果?

    或者每个原生的> JS调用需要异步_bridge enqueueJSCall

    文件: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}];
    
    }
    

    文件:index.js(原生模块)

     // 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 个答案:

答案 0 :(得分:2)

不确定Internal bridge module Java Script method是什么意思,但JS代码可以通过方法将数据传递给native,而native可以通过回调或promises将数据返回给JS。本机代码也可以向JS发送事件。

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

有关更多详细信息,请参阅本机模块文档: - https://facebook.github.io/react-native/docs/native-modules-ios.html - https://facebook.github.io/react-native/docs/native-modules-android.html

答案 1 :(得分:2)

我建议在React Native中对Batched Bridge进行一些阅读。

原生 - > JS

基本上你可以做的是在JS端定义一个带有静态方法的模块,然后你可以用BatchedBridgeregisterCallableModule)注册 - 这样你就可以直接调用这个方法了。本地方通过RCTBridge().enqueueJSCall,您将分别提供与您的模块和功能相对应的moduleDotMethod;您还可以传递一个唯一的(或增量的)标识符,稍后您将使用该标识符将响应映射到每个请求。

JS - >天然

接下来,您将创建一个在JS端调用的本机模块,将数据发送回本机,传递响应数据和标识符,然后在本机端处理。

我曾参与过整个服务层都在JS方面并成功使用这种方法的项目。