WebView是顯示網頁的主要控件,在實際工作共經常會用到,尤其是當需要與用戶有交互的時候,就會用到js,對於不太熟悉js的同事來說可能有點蒙,我們今天就來總結一下webview與js交互功能。
iOS12以後的版本不在支持UIWebView,用WebKit庫來代替了,我們在這裏只討論WKWebView。我們先來看下WebKit常用的幾個類:
- WKWebViewConfiguration配置webview的一些屬性
-
WKUserScript注入js腳本
-
WKUserContentController與js交互的代理
-
WKPreferences一些偏好設置
-
WKWebView顯示網頁H5
我們通過一個demo來看下。文章最後附上demo鏈接。
xcode版本:Version 10.1 (10B61) 語言:swift 4.2
- 原生控件調用js函數
let config = WKWebViewConfiguration();
let preferences = WKPreferences();
preferences.javaScriptEnabled = true;
preferences.javaScriptCanOpenWindowsAutomatically = false;
preferences.minimumFontSize = 16;
config.preferences = preferences;
let userContent = WKUserContentController();
userContent.add(self, name: "jsFunc");
config.userContentController = userContent;
webView = WKWebView(frame: self.view.bounds, configuration: config);
let url = Bundle.main.url(forResource: "TestHTML", withExtension: "html", subdirectory: "html");
webView.load(URLRequest(url: url!));
view.addSubview(webView);
首先創建一個web網頁,我們打開執行腳本屬性javaScriptEnabled設置爲true,然後創建一個原生的按鈕
let buttn = UIButton(frame: .init(x: 20, y: self.view.frame.height - 100, width: self.view.frame.width - 40, height: 40));
buttn.setTitle("原生按鈕 添加文字", for: .normal);
buttn.backgroundColor = UIColor.orange;
buttn.addTarget(self, action: #selector(sendMesageJS), for: .touchUpInside);
view.addSubview(buttn);
調用如下函數:
@objc func sendMesageJS() -> Void {
webView.evaluateJavaScript("insertTextToHTML()") { (result, error) in
};
}
接下來我們看html網頁和js:
先創建一個HTML網頁:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="TestCSS.css" />
<title>css</title>
<script type="text/javascript" src="TestJS.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1, maximum-scale=1, user-scalable=false" />
</head>
<body>
<button type="button" οnclick="jsSendMessage()">網頁按鈕 發送js消息</button>
</body>
</html>
然後在創建一個js腳本:
function insertTextToHTML(){
var body = document.getElementsByTagName('body');
let p = document.createElement('p');
p.innerText = "我是來自swift調用";
body[0].appendChild(p);
}
我們swift的button也就是原生的按鈕調用的函數必須和註冊到js的函數是一直的我們這個函數也可以動態註冊,如下的寫法:
func registerJS() -> String {
let js = """
function insertTextToHTML(){
var body = document.getElementsByTagName('body');
let p = document.createElement('p');
p.innerText = "通過註冊 我是來自swift調用";
body[0].appendChild(p);
}
""";
return js;
}
在配置webview上加上下面一句:
let js = WKUserScript(source: registerJS(), injectionTime: .atDocumentEnd, forMainFrameOnly: false);
userContent.addUserScript(js);
我們就可以直接用我們註冊到js的函數了。
- js發送消息。
我們配置webview的時候有userContent.add(self, name: "jsFunc");這麼一段代碼,這個是註冊一個方法的名字。我們再來看js代碼:
function jsSendMessage() {
window.webkit.messageHandlers.jsFunc.postMessage("js發送消息給Swift");
}
這一段是js代碼。我們必須保證window.webkit.messageHandlers.jsFunc.postMessage的函數名字必須和註冊時的名字一樣,這樣我們才能正確的發送消息。
我們需要實現WKUserContentController代理如下:
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
let mesg = message.body as! String;
let alert = UIAlertController(title: "提示", message: "swift收到js的信息:\n\(mesg)", preferredStyle: .alert);
alert.addAction(UIAlertAction(title: "確定", style: .default, handler: { (action) in
}));
present(alert, animated: true) {
};
}
這樣就可以js發送給swift,swift也可以正確接收了。