// // SYWebVC.swift // // Created by 张丰 on 2023/6/8. // import UIKit import WebKit import Reachability class SYWebVC: UIViewController { var urlStr = "" lazy var webview: WKWebView = WKWebView() lazy var progressbar: UIProgressView = UIProgressView() var native = XFNativeModule.init() var loadCount = 0 /// 网络监听类 lazy var reachability = try? Reachability() /// false没网 true有网 var netWortStatus = true func regisJsHandler(isInstall:Bool) { let handerContro = self.webview.configuration.userContentController for fun in AppJsFunType.allCases { if isInstall { handerContro.add(self, name: fun.rawValue) } else { handerContro.removeScriptMessageHandler(forName: fun.rawValue) } } } deinit { self.webview.removeObserver(self, forKeyPath: "estimatedProgress") self.webview.scrollView.removeObserver(self, forKeyPath: "contentOffset") } init(_ url:String) { super.init(nibName: nil, bundle: nil) self.urlStr = url } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() self.webview.navigationDelegate = self self.view.addSubview(self.webview) self.webview.frame = self.view.frame self.webview.translatesAutoresizingMaskIntoConstraints = false self.view.addConstraints([ self.webview.topAnchor.constraint(equalTo: self.view.topAnchor), self.webview.bottomAnchor.constraint(equalTo: self.view.bottomAnchor), self.webview.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), self.webview.trailingAnchor.constraint(equalTo: self.view.trailingAnchor), ]) self.webview.addSubview(self.progressbar) self.progressbar.tintColor = color_main self.setProgressBarPosition() webview.scrollView.addObserver(self, forKeyPath: "contentOffset", options: .new, context: nil) self.progressbar.progress = 0.1 webview.addObserver(self, forKeyPath: "estimatedProgress", options: .new, context: nil) self.regisJsHandler(isInstall: true) NetworkStatusListener() self.loadWeb() } func setProgressBarPosition() { self.progressbar.translatesAutoresizingMaskIntoConstraints = false self.webview.removeConstraints(self.webview.constraints) self.webview.addConstraints([ self.progressbar.topAnchor.constraint(equalTo: self.webview.topAnchor, constant: self.webview.scrollView.contentOffset.y * -1), self.progressbar.leadingAnchor.constraint(equalTo: self.webview.leadingAnchor), self.progressbar.trailingAnchor.constraint(equalTo: self.webview.trailingAnchor), ]) } @objc func loadWeb() { if webview.url != nil { webview.reload() } else { guard let url = URL.init(string: self.urlStr) else { return } self.webview.load(URLRequest.init(url: url)) } // guard let url = Bundle.main.url(forResource: "webte.html", withExtension: nil) else { return } // let req = URLRequest(url: url) // self.webview.load(req) } // MARK: - Web view progress override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { switch keyPath { case "estimatedProgress": if self.webview.estimatedProgress >= 1.0 { UIView.animate(withDuration: 0.3, animations: { () in self.progressbar.alpha = 0.0 }, completion: { finished in self.progressbar.setProgress(0.0, animated: false) }) } else { self.progressbar.isHidden = false self.progressbar.alpha = 1.0 progressbar.setProgress(Float(self.webview.estimatedProgress), animated: true) } case "contentOffset": self.setProgressBarPosition() default: super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) } } } extension SYWebVC:WKNavigationDelegate,WKUIDelegate { func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) { } func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) { } } extension SYWebVC:WKScriptMessageHandler { func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { SYLog("js调用原生的方法:\(message.name)") SYLog("js调用原生的方法的参数:\(message.body)") guard let type = AppJsFunType.init(rawValue: message.name) else { return } guard let param = message.body as? [String:Any] else { return } guard let data = param["data"] as? [String:Any] else { return } guard let callId = param["callId"] as? String else { return } switch type { case .initRCWithAppKey: guard let appkey = data["appKey"] as? String else { return } native.initRC(withAppKey: appkey, option: data) case .connectRC: guard let token = data["token"] as? String else { return } native.connectRC(token) { [weak self] value, keepAlive in guard let this = self else { return } this.callJS(callId: callId, data: value,keepAlive: keepAlive) } case .addRCConnectionListen: native.addRCConnectionListen { [weak self] value, keepAlive in guard let this = self else { return } this.callJS(callId: callId, data: value,keepAlive: keepAlive) } case .disConnectRC: native.disConnectRC() case .getLocation: native.getLocation(data) { [weak self] value, keepAlive in guard let this = self else { return } this.callJS(callId: callId, data: value,keepAlive: keepAlive) } case .stopLocation: native.stopLocation(data) case .isBackground: let isBackground = native.isBackground() self.callJS(callId: callId, data: ["isBackground":isBackground],keepAlive: false) case .callAction: native.callAction(data) case .getIt: debugPrint("回调成功") } } } extension SYWebVC { /// 调用JS func callJS(callId:String,data:Any?,keepAlive:Bool = false) { var param = [String:Any?]() param["keepAlive"] = keepAlive param["data"] = data let jsString = callId + "(" + convertDictionaryToString(dict: param) + ")" self.webview.evaluateJavaScript(jsString) { value, error in if let error { debugPrint(error) }else if let value { debugPrint(value) } } } } extension SYWebVC { /***** 网络状态监听部分(开始) *****/ func NetworkStatusListener() { // 1、设置网络状态消息监听 2、获得网络Reachability对象 NotificationCenter.default.addObserver(self, selector: #selector(self.reachabilityChanged),name: Notification.Name.reachabilityChanged,object: nil) do{ // 3、开启网络状态消息监听 try reachability?.startNotifier() }catch{ print("could not start reachability notifier") } } // 主动检测网络状态 @objc func reachabilityChanged(note: NSNotification) { switch reachability?.connection { case .wifi,.cellular: debugPrint("有网") netWortStatus = true if self.loadCount == 0 { self.loadWeb() self.loadCount = 1 } else { // self.emptyView.isHidden = true } default: netWortStatus = false debugPrint("断网") } } }