最近一直在學習前端的內容,這里總結一下js在不同載體的情況下與原生的交互。
react-Native調用原生
原生需要導入#import <React/RCTBridgeModule.h>框架,并且遵守RCTBridgeModule協議
在實現里面導出模塊(不添加參數即默認為這個類名)
RCT_EXPORT_MODULE();
然后需要導出方法
// 導出方法,橋接到js的方法返回值類型必須是void
RCT_EXPORT_METHOD(doSomething:(NSString *)testStr) {
NSLog(@"%@ ===> doSomething",testStr);
}
帶有回調的方法這么處理
/* 回調參數至少為兩個,第一個為狀態,第二個為參數 */
RCT_EXPORT_METHOD( doSomething1:(NSString *)testStr callBack:(RCTResponseSenderBlock)callback ){
NSLog(@"%@ ===> doSomething",testStr);
NSString *str1 = @"Callback數據"; //準備回調回去的數據
NSString *str2 = @"Callback數據222";
callback(@[[NSNull null],str1,str2]);
}
在react-native這么調用方法
//NativeAndRNBridge為原生定義的導出模塊
var NativeTest = require('react-native').NativeModules.NativeAndRNBridge;
NativeTest.doSomething1(('RN->原生的數據'),(error,str1,str2) => {
if (!error) {
alert(str1+"========"+str2)//返回的數據
} else {
console.warn(error);
}
});
Native調用UIWebView
UIWebView與Native交互時需要獲取JSContext,JSContext是JavaScriptCore里面的一個類
首先你需要定義一個屬性
@property(nonatomic,strong)JSContext *context;
在網頁加載完成的這個代理方法里面通過KVC獲取context
- (void)webViewDidFinishLoad:(UIWebView *)webView{
[self hidenChrysanthemum];
self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
//設置異常處理
self.context.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
context.exception = exceptionValue;
};
self.context[@"HrefLinkTaobao"] = ^(NSString * url){
dispatch_async(dispatch_get_main_queue(), ^{
//dosomething
});
};
self.context[@"HrefLinkLocal"] = ^(NSString * url){
dispatch_async(dispatch_get_main_queue(), ^{
//dosomething
});
};
self.context[@"native"] = self;
}
這里有一些注意點:
1、這里是有循環應用的問題,如果在方法的block中執行一些代碼,用到了self需要對self進行weak操作一下。
2、線程的問題,調用web的方法都是異步線程去調取的,所以回到原生的里面,做一些操作(非耗時)的時候最好是轉到主線程里面來