JS与原生OC/Swift相互调用总结

JS和OC/Swift相互调用,主要总结了JS和OC交互的三种方式
1.使用UIWebView,利用JavaScriptCore实现
2.使用WKWebView,利用WKScriptMessageHandler实现
3.使用第三方框架WebViewJavascriptBridge实现

JavaScriptCore

在Swift中获取JS的context

context = webView.value(forKeyPath: "documentView.webView.mainFrame.javaScriptContext") as? JSContext

注入JS需要的对象,对象命名与html中使用的保持一致.self是遵守了JSExport协议,也可是其他遵守协议的对象。

context?.setObject(self, forKeyedSubscript:  "OC" as NSCopying & NSObjectProtocol)

JS调用Swift的方法,在Swift中实现协议

@objc protocol JSDelegate :JSExport {
    //包含参数的func,需要注意参数名对函数名称的影响
    func showMessageToYou(_ message:String)
    
    /*
     对应html中“showAAndB”,此方法包含两个参数,需要在参数前加“_”
     func showA(_ aString: String, andB: String)
     func showAAndB(_ aString:String,_ bStr:String)
     以上两个方法等同
     */
    func showAAndB(_ aString:String,_ bStr:String)
    
    func doActionCallBack()
}

Swift调用JS的方法

let jsStr = String(format:"callback('%@')",(textField?.text)!)
self.context?.evaluateScript(jsStr)

OC中可使用block和实现JSExport协议两种方式实现,代码实现:

JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
self.context = context;
//注入JS需要的“OC”对象,该对象与html中的保持一致即可
self.context[@"OC"] = self;

WKScriptMessageHandler

初始化WKWebView后,添加供js调用oc/Swift的桥梁,这里的name对应WKScriptMessage中的name

webView.configuration.userContentController.add(_ scriptMessageHandler: WKScriptMessageHandler, name: String)

遵守协议WKScriptMessageHandler,实现以下方法,可实现JS把消息发送给OC/Swift。

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)

OC/Swift调用JS

let jsStr = String(format:"callback('%@')",(textField?.text)!)
self.webView.evaluateJavaScript(jsStr as String, completionHandler: { (result:Any?, error:Error?) in
       print("error:",error as Any)
 })

WebViewJavascriptBridge

初始化WKWebViewJavascriptBridge

self.webViewBridge = [WKWebViewJavascriptBridge bridgeForWebView:self.webView];
[self.webViewBridge setWebViewDelegate:self];

JS调用OC需要注册事件

[self.webViewBridge registerHandler:@"handlerName" handler:^(id data, WVJBResponseCallback responseCallback) {
   //code
}];

OC调用JS

[self.webViewBridge callHandler:@"handlerName" data:@[textField.text] responseCallback:^(id responseData) {
        NSLog(@"%@",responseData);
 }];

html中需要放置以下代码

/*这段代码是固定的,必须要放到js中*/
function setupWebViewJavascriptBridge(callback) {
    if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
    if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
    window.WVJBCallbacks = [callback];
    var WVJBIframe = document.createElement('iframe');
    WVJBIframe.style.display = 'none';
    WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
    document.documentElement.appendChild(WVJBIframe);
    setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
}
/*与OC交互的所有JS方法都要放在此处注册,才能调用通过JS调用OC或者让OC调用这里的JS*/
setupWebViewJavascriptBridge(function(bridge) {
     bridge.registerHandler('callback', function(data, responseCallback) {
        callback(data);
        responseCallback('js执行过了'+data);
    })
})
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 最近整理了一下原生与H5之间的交互方式,简单的做个总结。OC端与JS的交互,大致有这几种:拦截协议、JavaScr...
    谈Xx阅读 31,201评论 41 75
  • 随着H5技术的兴起,在iOS开发过程中,难免会遇到原生应用需要和H5页面交互的问题。其中会涉及方法调用及参数传值等...
    Chris_js阅读 3,131评论 1 8
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,262评论 4 61
  • 一、利用WebViewJavascriptBridge实现Native和Web的交互 参考链接1参考链接2 四个必...
    CoderZb阅读 2,224评论 0 5
  • 前言 Web 页面中的 JS 与 iOS Native 如何交互是每个 iOS 猿必须掌握的技能。而说到 Nati...
    幽城88阅读 2,256评论 1 8