iOS(Swift语言) WKWebView js交互

WKWebView是苹果在iOS8新引进的框架,在做WKWebView的js交互的时候:

一、WKWebView调用JS

使用WKWebView的evaluateJavaScript 方法:举个例子如果js中有个name 方法

调用js方法很简单只要

webView.evaluateJavaScript("name1()"){ (result,error)
}

调用后会有闭包返回。

二、用JS调用WKWebView

首先需要在原生端做一些准备,在初始化WKWebView的时候要添加如下代码配置


let webConfiguration = WKWebViewConfiguration() //用于初始化Web视图的属性集合
let pref = WKPreferences() //WKPreferences对象封装用于web视图偏好设置。
pref.javaScriptEnabled = true
webConfiguration.preferences = pref
webConfiguration.userContentController = WKUserContentController()
//对象提供了JavaScript来和注入用户脚本到web视图的方式
webConfiguration.userContentController.add(self, name:"appModel")

此时必须遵守WKScriptMessageHandler协议,WKScriptMessageHandler协议有一个

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

}方法,这个方法就是js端调用WKWebView时的返回结果。如下就是js端调用代码。

window.webkit.messageHandlers.appModel.postMessage(msg);

以上就可以做到js和原生交互的目的。


问题1

内存泄露,只要在vc的deinit方法里面添加

webView.configuration.userContentController.removeAllUserScripts()就可以了。


问题2

有的时候会发现WKWebView的页面字体会比webview的小。这是因为html中少meta的配置。


一种解决方法是让写h5页面的同事添加在head里面添加

name="viewport"content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no,minimal-ui">


因为在我把webview 替换WKWebView的时候项目已经运行很长时间了,有一些网页有此字段,有一些没有。所以我就在WKWebView中自己注入了一个js方法

WKUserScript类可以注入js方法

WKUserScript的初始化方法 需要3个参数第一个是js脚本的源代码,脚本应该被注入到网页的时间,最后一个是一个布尔值,指示脚本是只应该注入到主框架(true)还是注入到所有框架(false)中。

注入如下js脚本源代码

let jsSource = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no'); document.getElementsByTagName('head')[0].appendChild(meta);"
//js脚本的源代码

let source = WKUserScript(source:jsSource, injectionTime:
WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: false)


注入时间最好在加载之后,因为不知道html 是不是有这个字段,应该以咱们添加的js为准。


webConfiguration.userContentController.addUserScript(source)



因为webView和WKWebView的js交互方式不一样,这样会导致js端也会跟着改动,这样很不好,考虑了一段时间怎么样才可以js端代码不用改动。如下是我想到的方法。


WKWebView注入一段js代码,让js端调用方法和以前一样就可以了。举个例子:

以前webView的时候js交互用的是JSContext,注入一个对象,和一个方法,这样在js端就一个直接用这个对象的方法了,假如以前注入的对象是app,方法是jsFunc(str:String) ,只要我注入一段

var app = {
   jsFunc : function(json)
    {
        window.webkit.messageHandlers.appModel.postMessage(json);
    }
};

这段js代码应该在加载html之前就应该注入所以:


WKUserScript(source: js源代码(上面的), injectionTime:

WKUserScriptInjectionTime.atDocumentStart, forMainFrameOnly: false)


测试下完全OK。


你可能感兴趣的:(iOS(Swift语言) WKWebView js交互)