swift中之WebViewJavascriptBridge的使用

//

//  SQWebViewController.swift

//  Quantbroker

//

//  Created by 曹亮亮 on 2019/9/21.

//  Copyright © 2019 huoju. All rights reserved.

//

 

import UIKit

import WebKit

import SwiftyJSON

 

class SQWebViewController: SQBaseViewController {

    var subUrl: String? = ""

    var urlStr: String? = ""

    var progBar = UIProgressView()

    var newContentOffsetY = CGFloat(0)

    var oldContentOffsetY = CGFloat(0)

    var bridge: WebViewJavascriptBridge?

    var webTitle: String?

    

    lazy var webView:WKWebView = {

        let config = WKWebViewConfiguration.init()

        config.preferences.javaScriptEnabled = true

        config.userContentController = WKUserContentController.init()

        config.userContentController .add(self, name: "setTitle")

        

        let preferences = WKPreferences.init()

        preferences.javaScriptCanOpenWindowsAutomatically = true

        config.preferences = preferences

        //web

        let webView = WKWebView.init(frame: CGRect.zero, configuration: config)

        self.webView = webView

        webView.frame = self.view.bounds

        webView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.bounds.height)

        return webView

    }()

    

    

    private func initUI() {

        

        self.view.addSubview(self.webView)

        

        

        self.view.backgroundColor = ThemeColor.sharedInstance.getBgColor()

        webView.scrollView.backgroundColor = ThemeColor.sharedInstance.getBgColor()

        webView.backgroundColor = ThemeColor.sharedInstance.getBgColor()

        webView.scrollView.bounces = false

        webView.scrollView.bouncesZoom = false

        

        progBar = UIProgressView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 10))

        progBar.progress = 0.0

        progBar.tintColor = QBColor_Orange

        progBar.trackTintColor = UIColor.clear

        webView.addSubview(progBar)

        webView.addObserver(self, forKeyPath: "estimatedProgress", options: NSKeyValueObservingOptions.new, context: nil)

        webView.addObserver(self, forKeyPath: "title", options: NSKeyValueObservingOptions.new, context: nil)

        webView.scrollView.contentInset = UIEdgeInsets.init(top: 0, left: 0, bottom: kTabBarHeight, right: 0)

        webView.uiDelegate = self

        webView.navigationDelegate = self

        webView.allowsBackForwardNavigationGestures = true

        webView.scrollView.delegate = self

        

        //禁止手势操作前进后退

        webView.allowsBackForwardNavigationGestures = false

        

    }

    

//    override func viewDidAppear(_ animated: Bool) {

//        super.viewDidAppear(animated)

//

//    }

    

    override func viewDidLoad() {

        super.viewDidLoad()

        

        self.initUI()

        self.configNav()

        self.configWebView(urlStr: self.urlStr!)

        self.configWebViewsubStr(urlStr: self.subUrl!)

        self.configBridge()

        self.configBridgeRegister()

        self.configBridgeCallHander()

    }

    func urlIsAvailable(urlStr: String) {

        guard let requestURL = URL.init(string: urlStr) else {

            return

        }

        var request = URLRequest.init(url: requestURL)

        request.httpMethod = "HEAD"

        let session: URLSession = URLSession.init(configuration: URLSessionConfiguration.default)

        let task = session.dataTask(with: request) { (data, response, error) in

            if (error == nil) {

                self.loadWithUrl(urlString: urlStr)

            }else{

                //不可用

                let url = getUrlWebsite(urlStr: urlStr)

                self.loadWithUrl(urlString: url)

            }

        }

    }

    

    func configNav() -> Void {

        

    }

 

    func configWebView(urlStr: String) -> Void {

        if isBlankString(value: urlStr as AnyObject){

            return

        }

        self.urlStr = urlStr

        let url = NSURL.fileURL(withPath: self.urlStr!)

        let request = URLRequest.init(url: url)

        webView.load(request)

    }

    

    func configWebViewsubStr(urlStr: String) -> Void {

        if isBlankString(value: urlStr as AnyObject){

            return

        }

        let baseUrl = QBURLManager.h5WebviewUrl

        self.urlStr = baseUrl + urlStr

        let url = NSURL.fileURL(withPath: self.urlStr!)

        let request = URLRequest.init(url: url)

        webView.load(request)

    }

    

    func configBridge() -> Void {

        //开启日志

        WebViewJavascriptBridge.enableLogging()

        self.bridge = WebViewJavascriptBridge.init(forWebView: self.webView)

        self.bridge?.setWebViewDelegate(self)

    }

    //js call oc

    

    func configBridgeRegister() -> Void {

        weak var weakSelf = self

        self.bridge?.registerHandler("funcName", handler: { (data, responseCallback) in

            

//            let dictParam:Dictionary = JSONSerialization.jsonObject(with: data as Any, options: .mutableContainers)

            // dictParam["data"]

//            let dic = ["name":"param","id":dictParam["param"]]

//            let vc = UIViewController()

//            weakSelf?.navigationController?.pushViewController(vc, animated: true)

        })

    }

    //oc call js

    func configBridgeCallHander() -> Void {

        self.bridge?.callHandler("ocCallJs", data: ["":""], responseCallback: { (reponseData) in

            

        })

    }

    public func loadWithUrl(urlString:String){

        var urlTemp = urlString

        if (urlString.hasPrefix("www.")) {

            urlTemp = "https://"+urlString

        }

        if let url = URL(string: urlTemp) {

            webView.load(URLRequest(url: url))

        }

    }

    

    @objc public func loadWithBaseUrl(urlString: String) {

        let BaseUrl = QBURLManager.h5WebviewUrl

        if let url = URL(string: BaseUrl + urlString) {

            webView.load(URLRequest(url: url))

        }

    }

    

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {

        if keyPath == "estimatedProgress" {

            self.progBar.alpha = 1.0

            progBar.setProgress(Float(webView.estimatedProgress), animated: true)

            //进度条的值最大为1.0

            if(self.webView.estimatedProgress >= 1.0) {

                UIView.animate(withDuration: 0.3, delay: 0.1, options: UIView.AnimationOptions.curveEaseInOut, animations: { () -> Void in

                    self.progBar.alpha = 0.0

                }, completion: { (finished:Bool) -> Void in

                    self.progBar.progress = 0

                })

            }

        }else if keyPath == "title" {

//            self.navigationItem.title = webView.title

            

            if (object as! UIView == webView){

                self.navigationItem.title = webView.title

            }else{

                super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)

            }

        }else{

            super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)

        }

    }

    

    deinit {

        webView.removeObserver(self, forKeyPath: "estimatedProgress")

        webView.removeObserver(self, forKeyPath: "title")

    }

 

}

 

 

 

 

extension SQWebViewController: WKUIDelegate, WKNavigationDelegate,WKScriptMessageHandler {

    

    // 页面开始加载时调用

    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {

        

    }

    // 页面加载失败时调用

    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {

        

    }

    // 当内容开始返回时调用

    func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {

        

    }

    // 页面加载完成之后调用

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {

        

//        //界面加载完成后 调用loginCallback() 参数格式{token,uid},uid为 accountid

//        let token = UserManager.shared.model.token

//        let uid = UserManager.shared.model.accountId

//

//        webView.evaluateJavaScript("loginCallback('{\"token\": \"\(token)\", \"uid\": \"\(uid)\" ,\"nightType\": \"\(ThemeColor.sharedInstance.getThemeType())\", \"language\": \"\(NSLocalizedString("language", comment: ""))\"}')", completionHandler: nil)

//        print("loginCallback('{\"token\": \"\(token)\", \"uid\": \"\(uid)\", \"nightType\": \"\(ThemeColor.sharedInstance.getThemeType())\", \"language\": \"\(NSLocalizedString("language", comment: ""))\"}')")

        webView.evaluateJavaScript("document.documentElement.style.webkitUserSelect='none';", completionHandler: nil)

        webView.evaluateJavaScript("document.documentElement.style.webkitTouchCallout='none';", completionHandler: nil)

        

    }

    //提交发生错误时调用

    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {

        

    }

    // 接收到服务器跳转请求即服务重定向时之后调用

    func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) {

        

    }

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

        decisionHandler(WKNavigationActionPolicy.allow)

    }

    

    

    // 监听通过JS调用警告框

    func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {

        let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)

        alert.addAction(UIAlertAction(title: NSLocalizedString("确定",  comment: ""), style: .default, handler: { (action) in

            completionHandler()

        }))

        self.present(alert, animated: true, completion: nil)

    }

    

    // 监听通过JS调用提示框

    func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {

        let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)

        alert.addAction(UIAlertAction(title: NSLocalizedString("确定",  comment: ""), style: .default, handler: { (action) in

            completionHandler(true)

        }))

        alert.addAction(UIAlertAction(title: NSLocalizedString("取消",  comment: ""), style: .default, handler: { (action) in

            completionHandler(false)

        }))

        self.present(alert, animated: true, completion: nil)

    }

    

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

        if message.name == "setTitle" {

            let body = message.body

            print(NSLocalizedString("点击了这个方法\(body)",  comment: ""))

 

        }

    }

 

    

    

}

 

 

 

 

/*

 1.获取网页title在原生 顶部显示

 

 2.界面加载完成后 调用loginCallback() 参数格式{token,uid},uid为 accountid

 

 3.原生的回退按钮,每次点击调用 goBackCallback()无参数

 

 4.在我的邀请界面. 存币生息界面,头部右上角加一个 列表的icon.分别跳转到 邀请收益明细,,存币明细

 */

 

 

extension SQWebViewController: UIScrollViewDelegate {

    func scrollViewDidScroll(_ scrollView: UIScrollView) {

        oldContentOffsetY = newContentOffsetY

        newContentOffsetY = scrollView.contentOffset.y

//        if (newContentOffsetY > oldContentOffsetY)  {

//

//        }else if (oldContentOffsetY - newContentOffsetY) >= 20  {

//

//        }

        

    }

}

 

posted @ 2019-10-08 10:22  sundayswift  阅读(1200)  评论(0)    收藏  举报