swift中WKWebView和H5的简单交互WKWebView
1. 创建WKWebView
let configuration =WKWebViewConfiguration.init()
configuration.selectionGranularity =WKSelectionGranularity.dynamic
//允许播放视频
configuration.allowsInlineMediaPlayback =true
let preferrnce =WKPreferences.init();
//设置是否⽀持javaScript
preferrnce.javaScriptEnabled =true
//不⽤通过交互是否可以打开窗⼝
preferrnce.javaScriptCanOpenWindowsAutomatically =true
configuration.preferences = preferrnce
// 通过JS与webview内容交互
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标题为例:
//1.需要发送⼀个js命令获取⽹页的标题
webView.evaluateJavaScript("document.title"){(data, error)in
}
IOS调⽤vue中的⽅法,那么在vue中,只需要将⽅法绑定到window中即可,ios就能够调⽤到
//vue中需要注册的⽅法
created(){
//供iso调⽤前需要绑定到window上
window.AppToHTMLUserInfo= this.AppToHTMLUserInfo;
},
//OC中调⽤
let methodName ="AppToHTMLUserInfo(\(lgoniInfoString()))"
wkWebView!.evaluateJavaScript(methodName){(data, error)in
print("data=====\(data) error=========\(error)")
}
如何实现实时的获取H5的标题,并且显⽰在导航栏:
⾸先我们知道WKWebView有⼀个属性title(⽀持KVO),这个属性值就是当前H5页⾯的标题当我们发送指令获取H5标题的时候,WKWebView会把H5的标题获取并赋值给这个title属性
js获取json的key和value想要实时获取H5标题,只需使⽤KVO监听title舒⼼即可
//2.需要使⽤webview来监听标题的实时改变
wkWebView.addObserver(self, forKeyPath:"title", w, context:nil)
override func observeValue(forKeyPath keyPath:String?, of object:Any?, change:[NSKeyValueChangeKey:Any]?, context:UnsafeMutableRawPointer?){ if keyPath =="title"{
if(object as!WKWebView)== wkWebView {
< = 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("在发送请求之前,决定是否跳转=====\(quest.url)")
do{
let url =try String.init(contentsOf: quest.url!)
if url.starts(with:"xiangzhengapp"){
//表⽰需要调⽤⽅法
print("取消访问这个地址====")
decisionHandler(WKNavigationActionPolicy.cancel)
}
}catch{
print("webView--error=======\(error)")
}
//表⽰允许
decisionHandler(WKNavigationActionPolicy.allow)
}
3.2 通过⽅法
通过调⽤⾮⽅法格式如下:
// JS调OC,需要 H5端统⼀如下写法,⽅法名就是交互的名称,数据就是JS给OC传的值
ssageHandlers.<⽅法名>.postMessage(<;数据>)
⾸先我们需要再app单注册和H5定义好的⽅法名称
注册⽅法configuration.userContentController.add(),在不适⽤之后需要移出,不然会形成循环引⽤
// 通过JS与webview内容交互
configuration.userContentController =WKUserContentController()
//注册js接ios中公⽤⽅法名称
configuration.userContentController.add(self, name: openAppMenu)
configuration.userContentController.add(self, name: openAppLogin)
configuration.userContentController.add(self, name: openAppPay)
//veAllScriptMessageHandlers()- 移出所有注册⽅法
//veScriptMessageHandler(forName: openAppMenu)-移出单个⽅法
实现WKScriptMessageHandler协议,通过代理⽅法接收,并解析
func userContentController(_ userContentController:WKUserContentController, didReceive message:WKScriptMessage){ //print("name========\(message.name)")
//print("body=======\(message.body)")
/**
1.JS传值⾸先需要约定,然后注册调⽤的⽅法名称: ->configuration.userContentController.add(self,
name: openAppMenu)
2.如果交互,没有任何参数的情况, JS传递必须传递⼀个null,如果不传递任何参数, IOS这边回调⽅法不会执⾏
3. 传递参数智能是⼀个,多个参数,也只会读取第⼀个参数,建议使⽤集合来传递参数
*/
if message.name == openAppMenu {
let cp_id = message.body as!Int
let detaileVC =ControllerToStroyBoard("HomeMian","home_ZNCPDetail")as!GYZNCP_DetailViewController detaileVC.currentCP_ID = cp_id
CurrentController().navigationController?.pushViewController(detaileVC, animated:true)
}else if message.name == openAppLogin {
//登录
let loginVC =ControllerToStroyBoard("Main","login")
CurrentController().navigationController?.pushViewController(loginVC, animated:true)
}else if message.name == openAppPay {
//⽀付
let order_id =(message.body as!String)ponents(separatedBy:",").first!
let payType =Int((message.body as!String)ponents(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));
// iOSInfo. username iOSInfo. token iOSInfo.avatar
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论