WKWebView
1. 创建WKWebView2 IOS调用H53. H5调用原生3.1 通过连接3.2 通过方法3.3 在网页加载之前,传递值给H5
1. 创建WKWebView
let configuration
= WKWebViewConfiguration.init()
configuration
.selectionGranularity
= WKSelectionGranularity.dynamic
configuration
.allowsInlineMediaPlayback
= true
let preferrnce
= WKPreferences.init();
preferrnce
.javaScriptEnabled
= true
preferrnce
.javaScriptCanOpenWindowsAutomatically
= true
configuration
.preferences
= preferrnce
configuration
.userContentController
= WKUserContentController()
let wkWebview
= WKWebView.init(frame
: frame
, configuration
: configuration
)
wkWebview
.navigationDelegate
= self
wkWebview
.uiDelegate
= self
wkWebview
.allowsBackForwardNavigationGestures
= true
2 IOS调用H5
我们可以通过以下方法来调用H5的方法,已获取H5标题为例:
webView
.evaluateJavaScript("document.title") { (data
, error
) in
}
IOS调用vue中的方法,那么在vue中,只需要将方法绑定到window中即可,ios就能够调用到
created(){
window
.AppToHTMLUserInfo = this
.AppToHTMLUserInfo;
},
let methodName
= "AppToHTMLUserInfo(\(lgoniInfoString()))"
wkWebView
!.evaluateJavaScript(methodName
) { (data
, error
) in
print("data=====\(data) error=========\(error)")
}
如何实现实时的获取H5的标题,并且显示在导航栏:
首先我们知道WKWebView有一个属性title(支持KVO),这个属性值就是当前H5页面的标题当我们发送指令获取H5标题的时候,WKWebView会把H5的标题获取并赋值给这个title属性想要实时获取H5标题,只需使用KVO监听title舒心即可
wkWebView
.addObserver(self, forKeyPath
: "title", options
: NSKeyValueObservingOptions.new, context
: nil)
override func observeValue(forKeyPath keyPath
: String?, of object
: Any?, change
: [NSKeyValueChangeKey : Any]?, context
: UnsafeMutableRawPointer?) {
if keyPath
== "title" {
if (object
as! WKWebView) == wkWebView
{
titlelable
.text
= wkWebView
.title
}
} else {
super.observeValue(forKeyPath
: keyPath
, of
: object
, change
: change
, context
: context
)
}
}
3. H5调用原生
3.1 通过连接
H5和app端可以置顶一种连接的形式,当app打开网页时 在delegate方法中截取连接,判断是否是定好的链接,然后再解析,并调用原生方法:
func webView(_ webView
: WKWebView, decidePolicyFor navigationAction
: WKNavigationAction, decisionHandler
: @escaping
(WKNavigationActionPolicy) -> Void) {
print("在发送请求之前,决定是否跳转=====\(navigationAction.request.url)")
do {
let url
= try String.init(contentsOf
: navigationAction
.request
.url
!)
if url
.starts(with
: "xiangzhengapp") {
print("取消访问这个地址====")
decisionHandler(WKNavigationActionPolicy.cancel
)
}
} catch {
print("webView--error=======\(error)")
}
decisionHandler(WKNavigationActionPolicy.allow
)
}
3.2 通过方法
通过调用非方法格式如下:
window
.webkit
.messageHandlers
.<方法名
>.postMessage(<数据
>)
首先我们需要再app单注册和H5定义好的方法名称注册方法configuration.userContentController.add(),在不适用之后需要移出,不然会形成循环引用
configuration
.userContentController
= WKUserContentController()
configuration
.userContentController
.add(self, name
: openAppMenu
)
configuration
.userContentController
.add(self, name
: openAppLogin
)
configuration
.userContentController
.add(self, name
: openAppPay
)
实现WKScriptMessageHandler协议,通过代理方法接收,并解析
func userContentController(_ userContentController
: WKUserContentController, didReceive message
: WKScriptMessage) {
if message
.name
== openAppMenu
{
let cp_id
= message
.body
as! Int
let detaileVC
= GYLP_Utils.getControllerToStroyBoard("HomeMian", "home_ZNCPDetail") as! GYZNCP_DetailViewController
detaileVC
.currentCP_ID
= cp_id
GYLP_Utils.getCurrentController().navigationController
?.pushViewController(detaileVC
, animated
: true)
} else if message
.name
== openAppLogin
{
let loginVC
= GYLP_Utils.getControllerToStroyBoard("Main", "login")
GYLP_Utils.getCurrentController().navigationController
?.pushViewController(loginVC
, animated
: true)
} else if message
.name
== openAppPay
{
let order_id
= (message
.body
as! String).components(separatedBy
: ",").first!
let payType
= Int((message
.body
as! String).components(separatedBy
: ",").last!)!
if payType
== 0 {
AlipaySDK.defaultService()?.payOrder(order_id
, fromScheme
: "zhongxiang", callback
: { (resultDic
) in
print("orderPay========\(resultDic)")
})
} else {
}
}
}
3.3 在网页加载之前,传递值给H5
app需要写的代码:
let param
= ["uid":GYUserInfo.user_uid()!, "token":GYUserInfo.user_token()!]
let data
= try? JSONSerialization.data(withJSONObject
: param
, options
: JSONSerialization.WritingOptions.prettyPrinted
)
let jsonString
= String.init(data
: data
!, encoding
: String.Encoding.utf8
)
let js
= "userInfo = \(jsonString!)"
let script
= WKUserScript.init(source
: js
, injectionTime
: WKUserScriptInjectionTime.atDocumentStart
, forMainFrameOnly
: true)
configuration
.userContentController
.addUserScript(script
)
H5 接收
mounted(){
let iOSInfo
= JSON.parse(JSON.stringify(window
.iOSInfo
));
}