JS和OC/Swift相互調(diào)用,主要總結(jié)了JS和OC交互的三種方式
1.使用UIWebView,利用JavaScriptCore實現(xiàn)
2.使用WKWebView坤邪,利用WKScriptMessageHandler實現(xiàn)
3.使用第三方框架WebViewJavascriptBridge實現(xiàn)
JavaScriptCore
在Swift中獲取JS的context
context = webView.value(forKeyPath: "documentView.webView.mainFrame.javaScriptContext") as? JSContext
注入JS需要的對象仗岖,對象命名與html中使用的保持一致.self
是遵守了JSExport協(xié)議,也可是其他遵守協(xié)議的對象朽们。
context?.setObject(self, forKeyedSubscript: "OC" as NSCopying & NSObjectProtocol)
JS調(diào)用Swift的方法合住,在Swift中實現(xiàn)協(xié)議
@objc protocol JSDelegate :JSExport {
//包含參數(shù)的func,需要注意參數(shù)名對函數(shù)名稱的影響
func showMessageToYou(_ message:String)
/*
對應(yīng)html中“showAAndB”,此方法包含兩個參數(shù)绸栅,需要在參數(shù)前加“_”
func showA(_ aString: String, andB: String)
func showAAndB(_ aString:String,_ bStr:String)
以上兩個方法等同
*/
func showAAndB(_ aString:String,_ bStr:String)
func doActionCallBack()
}
Swift調(diào)用JS的方法
let jsStr = String(format:"callback('%@')",(textField?.text)!)
self.context?.evaluateScript(jsStr)
OC中可使用block和實現(xiàn)JSExport協(xié)議兩種方式實現(xiàn)项钮,代碼實現(xiàn):
JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
self.context = context;
//注入JS需要的“OC”對象,該對象與html中的保持一致即可
self.context[@"OC"] = self;
WKScriptMessageHandler
初始化WKWebView后,添加供js調(diào)用oc/Swift的橋梁华望,這里的name對應(yīng)WKScriptMessage中的name
webView.configuration.userContentController.add(_ scriptMessageHandler: WKScriptMessageHandler, name: String)
遵守協(xié)議WKScriptMessageHandler哟玷,實現(xiàn)以下方法狮辽,可實現(xiàn)JS把消息發(fā)送給OC/Swift。
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)
OC/Swift調(diào)用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調(diào)用OC需要注冊事件
[self.webViewBridge registerHandler:@"handlerName" handler:^(id data, WVJBResponseCallback responseCallback) {
//code
}];
OC調(diào)用JS
[self.webViewBridge callHandler:@"handlerName" data:@[textField.text] responseCallback:^(id responseData) {
NSLog(@"%@",responseData);
}];
html中需要放置以下代碼
/*這段代碼是固定的巢寡,必須要放到j(luò)s中*/
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方法都要放在此處注冊喉脖,才能調(diào)用通過JS調(diào)用OC或者讓OC調(diào)用這里的JS*/
setupWebViewJavascriptBridge(function(bridge) {
bridge.registerHandler('callback', function(data, responseCallback) {
callback(data);
responseCallback('js執(zhí)行過了'+data);
})
})