在RN開發(fā)中不可避免的遇到需要Native擴(kuò)展的情況厦瓢,比如我們需要使用React-Native并沒有封裝的原生功能狂男,其次我們可能需要使用到多線程和性能要求比較高的功能敢靡,此時(shí)立哑,往往我們需要進(jìn)行Native擴(kuò)展蒲赂。
模塊和方法的定義
一個(gè)普通的Objective-C類和方法是不會(huì)被系統(tǒng)處理成模塊進(jìn)而被調(diào)用,模塊運(yùn)行時(shí)向系統(tǒng)注冊(cè)刁憋,同時(shí)告訴系統(tǒng)什么屬性和方法可以被JavaScript調(diào)用,模塊類必須遵守RCTBridgeModule協(xié)議木蹬,該協(xié)議中定義了作為模塊需要的屬性和方法以及宏定義至耻。
導(dǎo)出模塊宏:
RCT_EXPORT_MODULE
導(dǎo)出模塊方法宏:
RCT_EXPORT_METHOD
eg:導(dǎo)出模塊類
Objective-C代碼
#import <Foundation/Foundation.h>
#import "RCTBridgeModule.h"
@interface JJSRCTModule : NSObject<RCTBridgeModule>
@end
#import "JJSRCTModule.h"
#import <UIKit/UIKit.h>
@implementation JJSRCTModule
//導(dǎo)出模塊
RCT_EXPORT_MODULE()
導(dǎo)出模塊方法 只有導(dǎo)出告訴系統(tǒng)我們才可以在JavaScript中使用模塊方法
RCT_EXPORT_METHOD(testFunc:(NSString*)str1 index:(NSString*)str2){
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"test" message:@"test" delegate:nil cancelButtonTitle:str1 otherButtonTitles:str2, nil];
[alertView show];
});
}
@end
JavaScript使用代碼:
//導(dǎo)入模塊 JJSRCTModule就是添加的模塊 注意如果模塊名前綴包含了RCT,會(huì)被格式化去除
var myModule = require('NativeModules').JJSRCTModule;
myModule.testFunc("否","是");
回調(diào)函數(shù)
React-Native中允許JavaScript在調(diào)用擴(kuò)展方法中使用回調(diào)函數(shù)镊叁,回調(diào)block的定義:
typedef void (^RCTResponseSenderBlock)(NSArray *respone)
//接受多個(gè)參數(shù)尘颓,傳遞的參數(shù)和接受的參數(shù)要一一順序?qū)?yīng)
typedef void (^RCTResponseErrorBlock)(NSError* error)
//接受錯(cuò)誤參數(shù)的回調(diào)函數(shù)
eg:
Objective-C代碼
RCT_EXPORT_METHOD(testCallback:(CTRResponseSenderBlock) callBack ){
if(callBack){
callBack(@[@"hello,",@"world"]);
}
}
JavaScript代碼
myModule.testCallback((str1,str2)=>{
AlertIOS.alert(str1 + str2);
});
導(dǎo)出常量
React-Native允許暴露一些常量給JavaScript模塊使用,主要通過
-(NSDictionary*)constansToExport方法導(dǎo)出,需要注意的是常量導(dǎo)出在框架初始化期間導(dǎo)出到模塊配置表中晦譬,不能在運(yùn)行時(shí)在對(duì)導(dǎo)出的字典修改疤苹,因?yàn)檫@是無(wú)效的。
eg:
Objective-C代碼
-(NSDictionary*)constansToExport{
return @{@"version":@"1.0.1"};
}
JavaScript代碼
alert(myModule.version);
事件
React-Native實(shí)現(xiàn)了Native到JavaScript一種消息傳遞機(jī)制敛腌,Native可通過RCTEventDispatcher向JavaScript端的EventEmitter模塊發(fā)送事件消息卧土,由EventEmitter模塊通知該事件的訂閱者來(lái)響應(yīng)事件的響應(yīng)惫皱。
eg:
Objective-C代碼
-(id)init{
if (self = [super init]) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(enterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
}
return self;
}
-(void)enterBackground:(NSNotification*)notice{
NSLog(@"enterBackground");
//注意的坑:在使用eventDispatcher時(shí)候必須導(dǎo)入CRTEventDispatcher.h文件不然編譯不了
[self.bridge.eventDispatcher sendAppEventWithName:@"testNotice" body:@{@"key":@"Value"}];
}
JavaScript代碼
var subscription = NativeAppEventEmitter.addListener("testNotice",(reminder)=>{ console.log("get Message");});