Swift.WKWebView與Html文件的JS交互

效果圖

實現(xiàn)效果:

以最簡單的形式與最簡單的demo來實現(xiàn)WKWebView與HTML文件的JS交互方式.

包括Swift調用JS方法以及JS調用Swift原生方法.并傳遞各種類型參數

實現(xiàn)在控制臺打印JS中的Console.log內容.


1.添加WeakScriptMessageDelegate文件,用其作為與JS交互時的代理,防止出現(xiàn)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發(fā)消息的時候會用到
        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.實現(xiàn)調用JS方法

讓控制器實現(xiàn)WKNavigationDelegate協(xié)議

extension ViewController: WKNavigationDelegate{
    ///在網頁加載完成時調用js方法
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        webView.evaluateJavaScript("sayHello('js你好,我是從Swift傳來的')", completionHandler: nil)
    }
}

5.接收JS調用方法

讓控制器實現(xiàn)WKScriptMessageHandler協(xié)議

 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
        }
    }
}


截止以上功能已經全部實現(xiàn),接下來講一下與h5協(xié)同調試時很重要一部分,就是打印出JS方法中console.log的內容,這樣才能即時的,直觀的了解交互情況.安卓方面自帶了這個功能,但是WKWebView需要我們與H5同時添加代碼才能夠實現(xiàn).

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交互還是很簡單的,如果需要可以先在本地實現(xiàn),然后把html文件給做H5的同事參考一下.雙方多交流相信可以很快實現(xiàn).

有問題歡迎探討.

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市职抡,隨后出現(xiàn)的幾起案子峻凫,更是在濱河造成了極大的恐慌伯顶,老刑警劉巖礁蔗,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異挣跋,居然都是意外死亡,警方通過查閱死者的電腦和手機狞换,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門避咆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人修噪,你說我怎么就攤上這事查库。” “怎么了黄琼?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵樊销,是天一觀的道長。 經常有香客問我脏款,道長围苫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任撤师,我火速辦了婚禮剂府,結果婚禮上,老公的妹妹穿的比我還像新娘剃盾。我一直安慰自己腺占,他們只是感情好淤袜,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著衰伯,像睡著了一般铡羡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上意鲸,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天烦周,我揣著相機與錄音,去河邊找鬼怎顾。 笑死论矾,一個胖子當著我的面吹牛,可吹牛的內容都是我干的杆勇。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼饱亿,長吁一口氣:“原來是場噩夢啊……” “哼蚜退!你這毒婦竟也來了?” 一聲冷哼從身側響起彪笼,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤钻注,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后配猫,有當地人在樹林里發(fā)現(xiàn)了一具尸體幅恋,經...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年泵肄,在試婚紗的時候發(fā)現(xiàn)自己被綠了捆交。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡腐巢,死狀恐怖品追,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情冯丙,我是刑警寧澤肉瓦,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站胃惜,受9級特大地震影響泞莉,放射性物質發(fā)生泄漏。R本人自食惡果不足惜船殉,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一鲫趁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧利虫,春花似錦饮寞、人聲如沸孝扛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽苦始。三九已至,卻和暖如春慌申,著一層夾襖步出監(jiān)牢的瞬間陌选,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工蹄溉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留咨油,地道東北人。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓柒爵,卻偏偏與公主長得像役电,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子棉胀,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內容