WebView
项目中功能多了,就会加载一些H5界面。这个时候就会用到WebView。再复杂一点就会用到原生与H5交互。举个例子,项目中经常会有一些活动界面。然而这些活动界面总是在变化。用原生代码写,维护成本较高。这个时候就可以用H5代替。这就会用到H5与原生相互调用。
关于WebView的创建,H5加载页面。我就不贴出来代码了。直接说一下 JavaScriptCore框架。这是苹果解决与H5交互专用框架。框架中有几个类需要注意:
JSContext.h(联系H5与原生的桥梁功能与CoreData中的context类似);
JSValue.h(用于获取H5中的任意对象);
JSExport.h(一个协议调用的时候会用到);
最后要知道,所有的调用方法基本上都是在- (void)webViewDidFinishLoad:(UIWebView *)webView里面完成。也就是页面加载完成时候调用。
JSContext创建:
self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];//创建
self.context.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue)
{
context.exception = exceptionValue;
};检测是否创建成功
H5调用原生
使用block
H5代码:
<button onclick="myAction();" style="">点击按钮返回上一个页面</button>
//如需传值,在方法名后面的括号里面加上即可
原生代码:
self.context[@"myAction"] = ^(){
};
//在小括号中接收H5传过来的参数,需要保持类型一致,在大括号中实现调用原生的方法;
使用JSExport代理
<button onclick="native.myLog();">调用OC中myLog方法</button>
//在小括号中添加需要传递的参数
原生代码:
创建代理,当前控制器遵循代理即WebExport
@protocol WebExport <JSExport>
JSExportAs
(myLog ,- (void)myOCLog :(NSString *)string);
指定代理(在- (void)webViewDidFinishLoad:(UIWebView *)webView方法中)
self.context[@"native"] = self;
实现代理方法
- (void)myOCLog :(NSString *)string{
NSLog(@"%@");
}
以上就是JS调用原生的基本使用。
原生调用H5
H5代码
<b id="label">需要改变的标签</b>
原生代码(在你需要触发的地方添加)
JSValue *labelAction = self.context[@"labelAction"];//使用JSValue接收fangaf
[labelAction callWithArguments:@[@"你好"]];
参考文档
(https://www.jianshu.com/p/0428d0734379)
WKWebView
相对来说WKWebView交互起来就比较麻烦啦,感觉没有WebView顺手。同样关于WKWebView的创建我就不贴出代码了
H5调用原生
原生代码(在- (void)viewDidLoad 方法中)
//配置环境
self.configuration = [[WKWebViewConfiguration alloc]init];
self.userVC = [[WKUserContentController alloc]init];
//注册方法
[self.userVC addScriptMessageHandler:self name:@"sayhello"];
self.configuration.userContentController = self.userVC;
接收参数
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
NSLog(@"%@",message.body);
//body中就是接收的参数
}
H5代码
<html>
<head>
<script>
function say()
{
//前端需要用 window.webkit.messageHandlers.注册的方法名.postMessage({body:传输的数据} 来给native发送消息
window.webkit.messageHandlers.sayhello.postMessage({body: 'hello world!'});
//这句很重要,利用WKWebView的新特性MessageHandler来实现JS调用原生方法,很多博客都没有写上这句,所以导致我一直没有成功
}
</script>
</head>
<body>
<h1>hello world</h1>
<button onclick="say()">say hello</button>
</body>
</html>
原生调用H5
原生代码
- (void)webView:(WKWebView *)tmpWebView didFinishNavigation:(WKNavigation *)navigation{
//say()是JS方法名,completionHandler是异步回调block
[webView evaluateJavaScript:@"say()" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
NSLog(@"%@",result);
}];
}
网友评论