React Native(RCT_REMAP_METHOD):如何导出带有参数和返回值的方法?



我正在尝试在 React Native 上使用 gRPC。 首先,我能够用Objective-C设置我的gRPC模块。 接下来,我为该 gRPC 模块制作了一个本机模块。

gRPC 模块非常简单。

rpc CheckEmail(EmailCheckRequest) returns (EmailCheckResponse) {}
message EmailCheckRequest {
string email = 1;
}
message EmailCheckResponse {
common.RetCode ret = 1; 
}

如您所见,有一个输入参数(电子邮件地址(并返回"返回代码"。

我在 https://facebook.github.io/react-native/docs/native-modules-ios.html 检查了如何制作本机模块,它显示了如何使用参数制作模块或具有返回值的模块,但没有解释如何同时制作一个

。以下是示例。

带参数的模块

RCT_EXPORT_METHOD(addEvent:(NSString *)name)
{
RCTLogInfo(@"Pretending to create an event %@", name);
}

带有返回值的模块(实际上,带有承诺(

RCT_REMAP_METHOD(findEvents,
findEventsWithResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSArray *events = ...
if (events) {
resolve(events);
} else {
NSError *error = ...
reject(@"no_events", @"There were no events", error);
}
}

无论如何,基于此,我像这样编写了自己的代码。

RCT_REMAP_METHOD(checkEmail: (NSString *)email, resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
/* ... */
}

而 react-native side javascript 代码是这样的。 var NetworkService = NativeModules.NetworkService; var ret = NetworkService.checkEmail('spike@merong.com'(;

没有编译错误,但在运行应用程序时,XCode 在RCT_REMAP_METHOD行返回此运行时错误 "com.facebook.React.JavaScript (11(:EXC_BAD_ACCESS(code=1, address=0x88(

看起来RCT_REMAP_METHOD宏有问题,但不知道Objective-C的细节,也不知道如何使用marco。

如果有人知道如何使用宏导出带有参数和返回值RCT_REMAP_METHOD模块,或者我的代码有问题,请告诉我。

其他发现我遵循了RCT_REMAP_METHOD的定义,似乎可以使用RCT_EXPORT_METHOD来代替,因为 EXPORT 是 REMAP 的重新定义,并且有一个带有 EXPORT 的承诺的例子,但不确定这是否是正确的方法。

* ## Promises
*
* Bridge modules can also define methods that are exported to JavaScript as
* methods that return a Promise, and are compatible with JS async functions.
*
* Declare the last two parameters of your native method to be a resolver block
* and a rejecter block. The resolver block must precede the rejecter block.
*
* For example:
*
* RCT_EXPORT_METHOD(doSomethingAsync:(NSString *)aString
*                           resolver:(RCTPromiseResolveBlock)resolve
*                           rejecter:(RCTPromiseRejectBlock)reject
* { ... }
*
* Calling `NativeModules.ModuleName.doSomethingAsync(aString)` from
* JavaScript will return a promise that is resolved or rejected when your
* native method implementation calls the respective block.
*
*/

RCT_EXPORT_METHOD只是将js函数remap为本机函数。当多个本机方法在第一个冒号之前都相同并且具有冲突的 JavaScript 名称时,这很有用。

正如定义RCT_REMAP_METHOD(js_name, method)js_name表示从js代码调用的函数,method表示本机函数名称。

因此,如果要导出带有参数(或更多(的方法,可以这样做:

// Bridge.m
RCT_EXPORT_MODULE(Bridge)
RCT_REMAP_METHOD(findEvents,
type:(NSString *)type
params:(NSDictionary *)params
findEventsWithResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{ ... }

然后从 js 代码中,像这样调用函数:

const Bridge = NativeModules.Bridge;
class App extends Component {
asnyc _buttonPress() {
try {
let result = await Bridge.findEvents("type", {"key": "value"});
// handle the result
} catch(e) {
// handle the error
}
}
}

确保RCTPromiseResolveBlockRCTPromiseRejectBlock是最后两个参数。

正如我在附加查找部分提到的,我能够导出带有参数和返回值的模块,并带有RCT_EXPORT_METHOD。

RCT_EXPORT_METHOD(checkEmail: (NSString *)email 
resolver:(RCTPromiseResolveBlock)resolve 
rejecter:(RCTPromiseRejectBlock)reject)
{
/* ... */
}

通过这种方式,我能够导出"检查电子邮件"。

Javascript : NativeModules.ModuleName.checkEmail(email(;

我没有Objective-C背景知识,所以即使它以这种方式工作,如果我的代码有问题,请告诉我。 =(

最新更新