美文网首页ios实用开发技巧
iOS 与H5交互(WebView与WKWebView)

iOS 与H5交互(WebView与WKWebView)

作者: 雨洒潇湘 | 来源:发表于2018-01-10 16:07 被阅读219次

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);
    }];
    
}

参考文档

(https://www.jianshu.com/p/4fa8c4eb1316)

相关文章

网友评论

    本文标题:iOS 与H5交互(WebView与WKWebView)

    本文链接:https://www.haomeiwen.com/subject/vsnygxtx.html