1:简单交互(以WKWebView)
1:JS调用OC中的相应方法;

重写WebViewDelegate的回调方法- (void)webView:(WKWebView )webView decidePolicyForNavigationAction:(WKNavigationAction )navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler,在该方法中通过判断请求的URL的scheme来处理特定URL,可以处理原生页面的跳转、原生页面的弹窗等业务逻辑,然后调用decisionHandler(WKNavigationActionPolicyCancel);告诉WKWebView不用处理这个请求,这个请求已经让原生处理了。

WKWebViewConfiguration注入WKScriptMessageHandler
WKWebViewConfiguration对象需要使用调用方法 addScriptMessageHandler:name 来设置JS事件的接收处理器,

2:OC调用JS中的方法;

[webView evaluateJavaScript:@"testJS('abc')" completionHandler:nil];

注意:调用无参JS方法,小括号不能缺少

2:稍微复杂的交互(功能强大JavaScriptCore)
iOS JavaScriptCore使用
主要使用JavaScriptCore框架提供的JSContext与JSValue类;
JSContext --- 在OC中创建JavaScript运行的上下文环境;
JSValue --- JavaScript中的变量和方法,可以转成OC数据类型,每个JSValue都和JSContext相关联并且强引用context;
示例代码:

- (void)doSomeJsThings{
    self.jsContext = [_webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exception) {
        NSLog(@"出现异常,异常信息:%@",exception);
    };
    //oc调用js
    JSValue * nativeCallJS = self.jsContext[@"nativeCallJS"];
    [nativeCallJS callWithArguments:@[@"hello word"]];//调用了js中方法"nativeCallJS",并且传参数@"hello word"
    //在本地生成js方法,供js调用
    self.jsContext[@"jsCallNative"] = ^(NSString *paramer){
        JSValue *currentThis = [JSContext currentThis];
        JSValue *currentCallee = [JSContext currentCallee];
        NSArray *currentParamers = [JSContext currentArguments];
        dispatch_async(dispatch_get_main_queue(), ^{
            /**
             *  js调起OC代码,代码在子线程,更新OC中的UI,需要回到主线程
             */
            NSLog(@"js传过来:%@",paramer);
        });
        NSLog(@"JS paramer is %@",paramer);
        NSLog(@"currentThis is %@",[currentThis toString]);
        NSLog(@"currentCallee is %@",[currentCallee toString]);
        NSLog(@"currentParamers is %@",currentParamers);
    };//生成native的js方法,方法名:@"jsCallNative",js可直接调用此方法
}

3:使用方便(第三方库)
WKWebViewJavascriptBridge
源码解析
WKWebViewJavascrtptBridge.swift 负责WKWebView的封装,oc<->js的之间通信
1:利用WKWebViewConfiguration实现JS调用OC;
2:利用evaluateJavaScript实现OC调用JS

WKWebViewJavascriptBridgeBase.swift 负责对消息的内部处理以及标识
接收数据,进行数据的解析和序列化操作;同时调用WKWebViewJavascrtptBridge 传递内容;

WKWebViewJavascriptBridgeJS.swift 复制iOS原生调用js,和js调用iOS原生的一个接口,可以理解成一个js文件,这里存了一个window.WKWebViewJavascriptBridge对象,这个对象就是提供了用来协调js与iOS原生交互的一个重要枢纽
本质上,是在消息通信过程中,进行消息队列和事件的管理;

4:UIWebView与WKWebView的优缺点;
性能和稳定性的大幅提高
内存占用的减少,大概是UIWebView的1/4 - 1/3 参考链接
支持更多HTML5、JS特性
允许JavaScript的Nitro的库加载并使用(移动设备的 Safari 使用 Nitro 引擎,但是 UIWebView 不包括 JIT 编译,所以不支持,体验会慢一些)
60fps的刷新率以及内置手势的支持
增加了新的代理方法,可控性更高
estimatedProgress属性实现进度条
不需要像UIWebView一样自己做假进度条(通过NJKWebViewProgress和双层代理技术实现),技术复杂度和代码量,根贴近实际加载进度优化好的多。
JS交互上更方便

缺点:
1:在iOS9.0之前,加载document目录下的文件,真机无法显示,需要拷贝到tmp文件;
2:在iOS9.0之后,使用loadFileURL加载;

5:WKWebView的优化方向;
webVeiw加载或者渲染方法:
初始化 webview -> 请求页面 -> 下载数据 -> 解析HTML -> 请求 js/css 资源 -> dom 渲染 -> 解析 JS 执行 -> JS 请求数据 -> 解析渲染 -> 下载渲染图片
1:启动时间慢,可以考虑预先加载一个webView,然后在需要的时候加载对应网页,显示;
2:通过设置setCachePolicy,缓存网页加载的内容;
3:离线包下载 -> WKURLSchemeHandler(iOS11.0)

iOS App秒开H5

参考网址:
iOS WKWebView和JS交互的两种方式
https://www.jianshu.com/p/c988d9fe55f5
https://www.jianshu.com/p/42e38c912739