我们有很多业务场景需要实现信息传输的问题。这里来总结下iOS与JS交互问题,Android方式类似。
交互方式
< 1 > 协议拦截
我们可以让 H5开发人员在点击按钮的这个动作中,发起一个虚拟的请求(拼一个无效的 url,类似协议可以传给 native的信息拼入,iOS7.0之前普遍对接WebViewJavascriptBridge 原理类似;
实现:
@protocol UIWebViewDelegate
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
解析 NSURL *url = [request URL]; Match协议,进行拦截处理。
甚者不将 native的信息拼入,因为是无效 url,请求失败后H5端将需要传给 native 端的信息包入失败信息里面传给我们(多此一举)
< 2 > 对象注入
定义一个协议基于JSExport,然后定义一个Model 实现该协议;
通过webView的valueForKeyPath获取上下文,其路径为documentView.webView.mainFrame.javaScriptContext。
如果需要H5调用Native后进行值回调,可以直接进行参数返回,而不需进行多余的接口调用处理
H5:
const formData = window.jsmodel.myMethod(JSON.stringify(data));
Native: WebView 加载完成后,进行模型注入
self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
JsObjCModel *model = [[JsObjCModel alloc] init];
self.jsContext[@"jsModel"] = model; //jsModel 为JS调用使用
model.jsContext = self.jsContext;
model.webView = self.webView;
model.backblock = ^{
dispatch_async(dispatch_get_main_queue(), ^{
// [self.navigationController popViewControllerAnimated:YES];
});
};
self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
context.exception = exceptionValue;
LOG(@"异常信息:%@", exceptionValue);
};
JavaScriptCore
iOS7.0后出来的JavaScriptCore framework:
- JSContext, JSContext是代表JS的执行环境,通过-evaluateScript:方法就可以执行一JS代码;
- JSValue, JSValue封装了JS与ObjC中的对应的类型,以及调用JS的API等;
- JSExport, JSExport是一个协议,遵守此协议,就可以定义我们自己的协议,在协议中声明的API都会在JS中暴露出来,才能调用;
关于Native和H5的交互有各种形式,随着H5越来越成熟,Hybrid App也越来越多,在提高效率缩短开发周期和产品灵活性上有很大的作用.
网友评论