RN与JS交互之-封装iOS原生模块

本文要讲的交互场景是JS调用原生方法,最后由原生方法将结果回调到JS里面。

react-native是在原生的基础上,将接口调用统一为js。也就是说,react-native调起原生的能力非常重要。

本文基于react-native 0.44.3

1,引入头文件

#import <React/RCTBridgeModule.h>

2,遵守协议

@interface BaseNativeModule :  NSObject  <RCTBridgeModule>

3,导出模块

@implementation  BaseNativeModule

RCT_EXPORT_MODULE( moduleName ); //用于导出模块,可以设置导出的模块名,默认就是类名。

@end

4,导出方法:

RCT_EXPORT_METHOD(addEvent:(NSString*)name location:(NSString*)location)

{

//在js控制台上打印log信息。

RCTLogInfo(@"Pretending to create an event %@ at %@", name, location);

}

这个方法是一个实例方法。

5,js端调用。

import  { NativeModules } from 'react-native

NativeModules.XXX.addEvent( param1, param2 );

需要注意,jsbundle加载需要一个js线程,在jsbundle加载的时候,react-native会去配置NativeModules,它是一个对象,或者看成是一个map,key就是模块名,value就是原生的对象。一个key对应的原生对象只有一个,也就是说无论在RN页面的哪个地方调用这个原生模块,实际调用的是同一个对象,需要考虑对象状态的问题。

6,js回调

桥接到Javascript的方法返回值类型必须是void。React Native的桥接操作是异步的,在queue里面异步执行,所以如果要返回结果给Javascript,就必须通过回调或者触发事件来进行。这里讲的是回调。回调对应于iOS端就是通过block来回调的。

js回调的特点,发起方是js,必须是js端先发起,然后由native方回调结果到js端处理。

6.1 RCTResponseSenderBlock

这个block接受一个数组参数,数组里面有两个元素,第一个参数用于表示错误信息,第二个参数可以是一个数组,也可以是一个对象,总之第二个代表原生方法的返回结果,第一个代表获取成功还是失败。

6.2 Promise样式的回调。一般用于js端try-catch结构,和Promise调用。

RCTPromiseResolveBlock,对应js里面的resolve。

RCTPromiseRejectBlock,对应js里面的reject。

7,多线程

js代码的执行是在js线程里面,原生模块的执行默认是在一个串行的GCD queue里面异步执行的。对于原生模块的执行来说,默认一个串行的GCD queue是不够的,我们有时候需要指定模块所有任务执行所在的queue。

这个可以通过重写methodQueue的getter方法

 - (dispatch_queue_t)methodQueue

{

return dispatch_get_main_queue();

}

此外,如果一个模块里面的几个任务,个别任务需要在一个特殊的线程里面执行,那么只去在任务执行的逻辑里面,指定该任务执行所在的线程。

RCT_EXPORT_METHOD(doSomethingExpensive:(NSString *)param callback:(RCTResponseSenderBlock) callback)

{

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{

        // 在这里执行长时间的操作...

        // 你可以在任何线程/队列中执行回调函数callback(@[...]); });

}

在模块之间共享分发队列:

 methodQueue方法会在模块被初始化的时候被执行一次,然后会被React Native的桥接机制保存下来,所以你不需要自己保存队列的引用,除非你希望在模块的其它地方使用它。但是,如果你希望在若干个模块中共享同一个队列,则需要自己保存并返回相同的队列实例;仅仅是返回相同名字的队列是不行的。

8,参数类型转换。

js与原生互相调用,除了方法签名的不同,参数类型也是不同的,要把参数类型对应起来。react-native框架本身做了一些转换。包括下面这些:

string (NSString)

number ( NSInteger, float, double, CGFloat, NSNumber)

boolean (BOOL,NSNumber)

array (NSArray) 包含本列表中任意类型

object (NSDictionary) 包含string类型的键和本列表中任意类型的值

function (RCTResponseSenderBlock)

除此以外,任何RCTConvert类支持的的类型也都可以使用(参见RCTConvert了解更多信息)。RCTConvert还提供了一系列辅助函数,用来接收一个JSON值并转换到原生Objective-C类型或类。


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容