实现效果:
以最简单的形式与最简单的demo来实现WKWebView与HTML文件的JS交互方式.
包括Swift调用JS方法以及JS调用Swift原生方法.并传递各种类型参数
实现在控制台打印JS中的Console.log内容.
1.添加WeakScriptMessageDelegate文件,用其作为与JS交互时的代理,防止出现ViewController不释放的问题.
import UIKit
import WebKit
///内存管理,使用delegate类防止ViewController不释放
class WeakScriptMessageDelegate: NSObject, WKScriptMessageHandler {
weak var scriptDelegate: WKScriptMessageHandler?
init(_ scriptDelegate: WKScriptMessageHandler) {
self.scriptDelegate = scriptDelegate
super.init()
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
scriptDelegate?.userContentController(userContentController, didReceive: message)
}
deinit {
print("WeakScriptMessageDelegate is deinit")
}
}
2.声明WKWebView,并注册与JS交互的名称.
lazy var webView: WKWebView = {
///偏好设置
let preferences = WKPreferences()
preferences.javaScriptEnabled = true
let configuration = WKWebViewConfiguration()
configuration.preferences = preferences
configuration.selectionGranularity = WKSelectionGranularity.character
configuration.userContentController = WKUserContentController()
// 给webview与swift交互起名字,webview给swift发消息的时候会用到
configuration.userContentController.add(WeakScriptMessageDelegate(self), name: "logger")
configuration.userContentController.add(WeakScriptMessageDelegate(self), name: "redResponse")
configuration.userContentController.add(WeakScriptMessageDelegate(self), name: "blueResponse")
configuration.userContentController.add(WeakScriptMessageDelegate(self), name: "greenResponse")
configuration.userContentController.add(WeakScriptMessageDelegate(self), name: "yellowResponse")
var webView = WKWebView(frame: CGRect(x: 0,
y: 0,
width: UIScreen.main.bounds.width,
height: UIScreen.main.bounds.height),
configuration: configuration)
// 让webview翻动有回弹效果
webView.scrollView.bounces = false
// 只允许webview上下滚动
webView.scrollView.alwaysBounceVertical = true
webView.navigationDelegate = self
return webView
}()
3.Html文件样式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0,user-scalable=no"/>
</head>
<body>
名字:<span id="name"></span>
<br/>
<button style = "background-color: #ff0000;color: #FFFFFF;padding: 15px 32px;" onclick="redResponse()">红色</button>
<button style = "background-color: #0041ff;color: #FFFFFF;padding: 15px 32px;" onclick="blueResponse()">蓝色</button>
<button style = "background-color: #00d819;color: #FFFFFF;padding: 15px 32px;" onclick="greenResponse()">绿色</button>
<button style = "background-color: #ffe064;color: #FFFFFF;padding: 15px 32px;" onclick="yellowResponse()">黄色</button>
<!-- 添加这个script在项目头,这样swift才能打印console.log的内容 -->
<script>
var console = {};
console.log = function(message){window.webkit.messageHandlers['logger'].postMessage(message)
};
</script>
<script type="text/javascript">
///被swift调用的方法
function sayHello(text) {
console.log(text)
}
///调用swift方法的方式 window.webkit.messageHandlers.(swift注册的交互名).postMessage(传给swift的参数)
function redResponse() {
///没有参数传可以传任意值,让swift端不接收
window.webkit.messageHandlers.redResponse.postMessage("")
}
function blueResponse() {
window.webkit.messageHandlers.blueResponse.postMessage("蓝色")
}
function greenResponse() {
window.webkit.messageHandlers.greenResponse.postMessage(1)
}
function yellowResponse() {
window.webkit.messageHandlers.yellowResponse.postMessage(["1","2","3"])
}
</script>
</body>
</html>
4.实现调用JS方法
让控制器实现WKNavigationDelegate协议
extension ViewController: WKNavigationDelegate{
///在网页加载完成时调用js方法
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("sayHello('js你好,我是从Swift传来的')", completionHandler: nil)
}
}
5.接收JS调用方法
让控制器实现WKScriptMessageHandler协议
extension ViewController: WKScriptMessageHandler{
///接收js调用方法
func userContentController(_ userContentController: WKUserContentController,
didReceive message: WKScriptMessage) {
///在控制台中打印html中console.log的内容,方便调试
let body = message.body
if message.name == "logger" {
print("JS log:\(body)")
return
}
///message.name是约定好的方法名,message.body是携带的参数
switch message.name {
case "redResponse":
///不接收参数时直接不处理message.body即可,不用管Html传了什么
redRequest()
case "blueResponse":
blueRequest(string: message.body as! String)
case "greenResponse":
greenRequest(int: message.body as! Int)
case "yellowResponse":
yellowRequest(array: message.body as! [String])
default:
break
}
}
}
截止以上功能已经全部实现,接下来讲一下与h5协同调试时很重要一部分,就是打印出JS方法中console.log的内容,这样才能即时的,直观的了解交互情况.安卓方面自带了这个功能,但是WKWebView需要我们与H5同时添加代码才能够实现.
1.在html文件中声明console
<!-- 添加这个script在项目头,这样swift才能打印console.log的内容 -->
<script>
var console = {};
console.log = function(message){window.webkit.messageHandlers['logger'].postMessage(message)
};
</script>
<script type="text/javascript">
2.在swift文件中声明webView时使用configuration注册与JS交互名
configuration.userContentController.add(WeakScriptMessageDelegate(self), name: "logger")
3.在swift文件中接收方法里添加
///接收js调用方法
func userContentController(_ userContentController: WKUserContentController,
didReceive message: WKScriptMessage) {
///在控制台中打印html中console.log的内容,方便调试
let body = message.body
if message.name == "logger" {
print("JS log:\(body)")
return
}
}
demo地址:WKWebView-Script
使用WKWebView与H5交互还是很简单的,如果需要可以先在本地实现,然后把html文件给做H5的同事参考一下.双方多交流相信可以很快实现.
有问题欢迎探讨.