React Native(RCT_REMAP_METHOD):如何导出带有参数和 return 值的方法?
React Native(RCT_REMAP_METHOD) : How to export a method with a parameter and return value?
我正在尝试在 React Native 中使用 gRPC。
首先,我能够使用 Objective-C 设置我的 gRPC 模块。
接下来,我为那个 gRPC 模块制作了一个原生模块。
gRPC 模块非常简单。
rpc CheckEmail(EmailCheckRequest) returns (EmailCheckResponse) {}
message EmailCheckRequest {
string email = 1;
}
message EmailCheckResponse {
common.RetCode ret = 1;
}
如您所见,有一个输入参数(电子邮件地址)和 return 一个 "Return Code"。
我在 https://facebook.github.io/react-native/docs/native-modules-ios.html 检查了如何制作本机模块,它显示了如何制作带有参数的模块或带有 return 值的模块,但它没有解释如何制作两者兼而有之。
示例如下。
带参数的模块
RCT_EXPORT_METHOD(addEvent:(NSString *)name)
{
RCTLogInfo(@"Pretending to create an event %@", name);
}
具有 return 值的模块(实际上,有 Promise)
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端javascript代码是这样的。
var 网络服务 = NativeModules.NetworkService;
var ret = NetworkService.checkEmail('spike@merong.com');
没有编译错误,但是 运行 应用程序 XCode return 在 RCT_REMAP_METHOD 行出现此运行时错误
"com.facebook.React.JavaScript (11):EXC_BAD_ACCESS(代码=1, 地址=0x88)
看来RCT_REMAP_METHOD宏有问题,但不知道Objective-C细节,也不知道如何使用宏。
如果有人知道如何使用 RCT_REMAP_METHOD 宏来导出带有参数和 return 值的模块,或者如果我的代码有问题,请告诉我。
其他发现
我按照RCT_REMAP_METHOD的定义,好像用RCT_EXPORT_METHOD代替也可以,因为EXPORT是REMAP的重新定义,有一个Promises with 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.
*
*/
正如我在附加发现部分提到的,我能够导出一个带有参数和 return 值的模块 RCT_EXPORT_METHOD。
RCT_EXPORT_METHOD(checkEmail: (NSString *)email
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
/* ... */
}
通过这种方式,我能够导出 "checkEmail"。
Javascript : NativeModules.ModuleName.checkEmail(电子邮件);
我没有Objective-C背景知识,所以即使这样工作,如果我的代码有问题,请告诉我。 =)
RCT_EXPORT_METHOD
只是把js函数remap
转为native函数。当多个本机方法在第一个冒号之前相同并且具有冲突的 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
}
}
}
Make sure the RCTPromiseResolveBlock
and RCTPromiseRejectBlock
are the last two parameters.
我正在尝试在 React Native 中使用 gRPC。 首先,我能够使用 Objective-C 设置我的 gRPC 模块。 接下来,我为那个 gRPC 模块制作了一个原生模块。
gRPC 模块非常简单。
rpc CheckEmail(EmailCheckRequest) returns (EmailCheckResponse) {}
message EmailCheckRequest {
string email = 1;
}
message EmailCheckResponse {
common.RetCode ret = 1;
}
如您所见,有一个输入参数(电子邮件地址)和 return 一个 "Return Code"。
我在 https://facebook.github.io/react-native/docs/native-modules-ios.html 检查了如何制作本机模块,它显示了如何制作带有参数的模块或带有 return 值的模块,但它没有解释如何制作两者兼而有之。
示例如下。
带参数的模块
RCT_EXPORT_METHOD(addEvent:(NSString *)name)
{
RCTLogInfo(@"Pretending to create an event %@", name);
}
具有 return 值的模块(实际上,有 Promise)
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端javascript代码是这样的。 var 网络服务 = NativeModules.NetworkService; var ret = NetworkService.checkEmail('spike@merong.com');
没有编译错误,但是 运行 应用程序 XCode return 在 RCT_REMAP_METHOD 行出现此运行时错误 "com.facebook.React.JavaScript (11):EXC_BAD_ACCESS(代码=1, 地址=0x88)
看来RCT_REMAP_METHOD宏有问题,但不知道Objective-C细节,也不知道如何使用宏。
如果有人知道如何使用 RCT_REMAP_METHOD 宏来导出带有参数和 return 值的模块,或者如果我的代码有问题,请告诉我。
其他发现 我按照RCT_REMAP_METHOD的定义,好像用RCT_EXPORT_METHOD代替也可以,因为EXPORT是REMAP的重新定义,有一个Promises with 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.
*
*/
正如我在附加发现部分提到的,我能够导出一个带有参数和 return 值的模块 RCT_EXPORT_METHOD。
RCT_EXPORT_METHOD(checkEmail: (NSString *)email
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
/* ... */
}
通过这种方式,我能够导出 "checkEmail"。
Javascript : NativeModules.ModuleName.checkEmail(电子邮件);
我没有Objective-C背景知识,所以即使这样工作,如果我的代码有问题,请告诉我。 =)
RCT_EXPORT_METHOD
只是把js函数remap
转为native函数。当多个本机方法在第一个冒号之前相同并且具有冲突的 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
}
}
}
Make sure the
RCTPromiseResolveBlock
andRCTPromiseRejectBlock
are the last two parameters.