swift中WKWebView和H5的简单交互

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属性
    • 想要实时获取H5标题,只需使用KVO监听title舒心即可
//2.需要使用webview来监听标题的实时改变
        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 通过方法

  • 通过调用非方法格式如下:
// JS调OC,需要 H5端统一如下写法,方法名就是交互的名称,数据就是JS给OC传的值  
  window.webkit.messageHandlers.<方法名>.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)

 //configuration.userContentController.removeAllScriptMessageHandlers()- 移出所有注册方法
        //configuration.userContentController.removeScriptMessageHandler(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 = 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));
   // iOSInfo. username  iOSInfo. token iOSInfo.avatar
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值