最近一直在学习前端的内容,这里总结一下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的方法都是异步线程去调取的,所以回到原生的里面,做一些操作(非耗时)的时候最好是转到主线程里面来