#import <React/RCTBridgeModule.h>
@interface TestObjectForJS : NSObject<RCTBridgeModule>
@end
#import <React/RCTLog.h>
@implementation TestObjectForJS
RCT_EXPORT_MODULE(TestObject); //声明导出的模块名
//声明并实现导出的方法(实际上是类方法)
RCT_EXPORT_METHOD(testFunc:(NSString *)first location:(NSString *)second)
{
NSString *output = [first stringByAppendingString:second];
RCTLogInfo(@"Pretending to create an event: %@", output);
}
@end
import { NativeModules } from 'react-native';
NativeModules.TestObject.testFunc('11', '22')
RCT_EXPORT_METHOD 支持所有标准 JSON 类型,包括:
- string (NSString)
- number (NSInteger, float, double, CGFloat, NSNumber)
- boolean (BOOL, NSNumber)
- array (NSArray) 可包含本列表中任意类型
- object (NSDictionary) 可包含 string 类型的键和本列表中任意类型的值
- function (RCTResponseSenderBlock)
- RCTConvert 声明的也都可以支持
const date = new Date('1995-12-17T03:24:00');
NativeModules.TestObject.testFunc('11', '22', date.getTime())
也可以传递 Date的 toISOString().
const date = new Date('1995-12-17T03:24:00');
NativeModules.TestObject.testFunc('11', '22', date.toISOString())
而在native端,如果是接收时间戳参数,可以用 NSNumber 或是直接用 NSDate
RCT_EXPORT_METHOD(testFunc:(NSString *)first location:(NSString *)second time:(NSNumber*)time) {
NSDate * date = [RCTConvert NSDate:time];
……
}
RCT_EXPORT_METHOD(testFunc:(NSString *)first location:(NSString *)second time:(NSDate*)time)
{
}
如果是接收时间字符串,可以用 NSString 或是直接用 NSDate
RCT_EXPORT_METHOD(testFunc:(NSString *)first location:(NSString *)second time:(NSString*)time)
{
NSDate * date = [RCTConvert NSDate:time];
}
JS端:
NativeModules.TestObject.testFunc('11', '22', {
location: '4 Privet Drive, Surrey',
time: date.getTime(),
description: '...'
})
Native端:
RCT_EXPORT_METHOD(testFunc:(NSString *)first location:(NSString *)second param:(NSDictionary*)param){
}
Native端,函数可以带一个 RCTResponseSenderBlock 类型的callback,将多个数据返还给 JS。
RCT_EXPORT_METHOD(testCallback:(NSString *)first callback:(RCTResponseSenderBlock)callback)
{
if (callback) {
callback(@[@(1),@"b", @"afgg"]);
}
}
PS: native端的callback只能调用一次,否则JS端会报错(如果 testCallback 声明了两个callback参数,那么一个代码分支只能调用其中一个callback)
RCT_EXPORT_METHOD(testCallback:(NSString *)first
callback:(RCTResponseSenderBlock)callback
callback2:(RCTResponseErrorBlock)callback2)
{
BOOL b = YES;
if (b) {
if (callback) {
callback(@[@(1),@"b", @"afgg"]);
}
}
else {
if (callback2) {
callback2([NSError errorWithDomain:@"hello" code:1001 userInfo:nil]);
}
}
}
而在JS端,传入的callback函数可以带任意个参数,个数与 Native端传入的相同(如果JS端多出的声明参数,值会是 undefined
NativeModules.TestObject.testCallback("1", (i, s, s2, i2) => {
console.log('int='+i) //int=1
console.log('string='+s) //string=b
console.log('string2='+s2) //string2=afgg
console.log(‘int2='+s2) //int2=undefined
})
可以在native端发送指定的事件(带有参数)给JS端。 样例代码:
- (NSArray<NSString *> *)supportedEvents
{
return @[@"EventReminder"];
}
sendEventWithName:body: 方法来发送事件和数据const eventListener = new NativeEventEmitter(NativeModules.TestObject)
const listener = eventListener.addListener("hello", (data) => {
console.log("hello data="+data)
})
//用remove 取消监听
listener.remove()
React Native 在一个独立的串行 GCD 队列中调用Native的方法,但这属于实现的细节,并且可能会在将来的版本中改变。 如果要指定 native代码的执行线程,可以重写 methodQueue 方法。
- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}
PS:methodQueue方法会在模块被初始化的时候被执行一次,然后会被 React Native 的桥接机制保存下来。如果要重用队列,要用成员变量保存下来。