CNWebView.swift 10.2 KB
//
//  CNWebView.swift
//  metaCode
//
//  Created by zx on 2024/2/1.
//

import Foundation
import WebKit
import WebViewJavascriptBridge
import CNLiveShareToolKit
import CommonCrypto
import CNLiveBusinessTools
import SKPhotoBrowser

//更新Web控制器导航回调
typealias cnWebControllerUpdateNavBlock = (_ isFinish:Bool , _ titleName:String ,_ isDecidePolicy:Bool , _ urlStr:String)->Void

class CNWebView:UIView,WKNavigationDelegate{
    
    var configuration:WKWebViewConfiguration?
    
    lazy var cnWebView :WKWebView = {
        let cnWebView = WKWebView(frame: self.bounds, configuration: self.configuration!)
        return cnWebView
    }()

    var webUrl:URL?//初始URL
    var currentUrl:String = ""//当前网页的url
    var bridge:WKWebViewJavascriptBridge?
    
    //CNWebController
    var isCNWebController:Bool = false//是否网页控制器
    var webControllerUpdateNavBlock:cnWebControllerUpdateNavBlock?
    
    
    init(frame: CGRect, configuration: WKWebViewConfiguration ,url:URL?) {
        super.init(frame: frame)
        self.configuration = configuration
        self.addSubview(self.cnWebView)
        self.webUrl = url
        self.cnWebView.evaluateJavaScript("navigator.userAgent") { [self] result, error in
            let userAgent = result as! String
            if error == nil && userAgent.count > 0 {
                if !userAgent.contains(CNLiveMCEnvironmentManager.shared.base_web_UA) {
                    let newUserAgent = userAgent + CNLiveMCEnvironmentManager.shared.base_web_UA
                    self.cnWebView.customUserAgent = newUserAgent
                    
                    if (self.webUrl != nil){
                        let urlStr = self.checkURLWithStr(urlStr: self.webUrl!.absoluteString)
                        self.currentUrl = urlStr

                        self.cnWebView.load(URLRequest.init(url:URL(string: urlStr)!))
                    }
                    self.configBridge()
                    self.configBridgeRegister()
                }
            }
        }
    }
    
    func configBridge(){
        WKWebViewJavascriptBridge.enableLogging()
        self.bridge = WKWebViewJavascriptBridge(for: self.cnWebView)
        self.bridge?.setWebViewDelegate(self)
    }
    //h5拉起原生
    func configBridgeRegister() -> Void {
        //h5拉起原生分享 js call oc
        self.bridge?.registerHandler("wjjylzgVideoShare", handler: { data, responseCallback in
//            print("js call oc\(data)")
            let dic = data as! Dictionary<String, String>
            CNLiveShareManager.showShareViewWithParam(forShareTitle: dic["title"], shareUrl: dic["shareUrl"], shareDesc: dic["subTitle"], shareImage: dic["cover"], screenFull: false, hiddenWjj: true, hiddenQQ: false, hiddenWB: true, hiddenLifeCircle: true, hiddenWechatCircle: false, hiddenWechat: false, hiddenSafari: true, formVC: currentViewController(), topImage: [], topTitles: [], platformType: .all) { title in
                
            } completerBlock: { resultType, platformType, typeString in
                if resultType == .succ{
                    
                }
            }

        })
        // 网页内容图片预览
        self.bridge?.registerHandler("wjjPreviewImage", handler: { data, responseCallback in
            //            print("js call oc\(data)")
            var images = [SKPhoto]()
            let dic = data as! Dictionary<String, Any>
            let index = (dic["index"] as! NSString).integerValue
            let imageArray = dic["imgArr"] as! NSArray
            var imgArray = NSMutableArray()
            for dict in imageArray {
                var imgUrl = ""
                if let dictemp = dict as? String{
                    imgArray.add(dictemp)
                    imgUrl = dictemp
                }else if let dictemp = dict as? Dictionary<String, Any>{
                    imgArray.add(dictemp["src"] ?? "")
                    imgUrl = dictemp["src"] as! String
                }
                let photo = SKPhoto.photoWithImageURL(imgUrl)
                photo.shouldCachePhotoURLImage = false
                photo.photoURL = imgUrl
                images.append(photo)
            }
            let browser = SKPhotoBrowser(photos: images)
            browser.initializePageIndex(index)
            currentViewController()?.present(browser, animated: true)

        })
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func checkURLWithStr(urlStr:String) -> String{
        if URL(string: urlStr)?.host != WjjH5 {
            return urlStr//不是wjjh5不作处理
        }
        var str = urlStr
        let date = Date()
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyyMMdd"
        let dateStr = formatter.string(from: date)
        let sidStr = String(format: "%@%@", UserInfoManager.shared.userInfo.uid,dateStr)
        let signStr = sidStr.crypt(operation:  CCOperation(kCCEncrypt), key: CNLiveMCEnvironmentManager.shared.appKey)
        let sidSignStr = (signStr ?? "").isEmpty ?  "" : signStr
        let sourceArray = str.components(separatedBy: "?")
        let buildVersion = Bundle.main.infoDictionary!["CFBundleVersion"] as! String
        let appVersion = Bundle.main.infoDictionary!["CFBundleShortVersionString"] as! String
        let uuid = CNLiveBusinessTools.getUidForStat(Date())
        if sourceArray.count == 1{
            //是wjjh5且无参数
            str = String(format: "%@?shareSid=%@&sid=%@&plat=i&ver=%@&version=%@&wjjFrom=apple&wjjUUID=%@&appId=%@&voteId=%@&wjjToken=%@", str,UserInfoManager.shared.userInfo.uid,UserInfoManager.shared.userInfo.uid,buildVersion,appVersion,uuid,CNLiveMCEnvironmentManager.shared.appId,sidSignStr!,UserInfoManager.shared.userInfo.token)
            return str
        }
        //是wjjh5且有参数
        let paraArr = NSMutableArray(array: ["shareSid=","sid=","plat=","ver=","version=","wjjFrom=","wjjUUID=","appId=","voteId=","wjjToken="])
        let valueArr = NSMutableArray(array:[UserInfoManager.shared.userInfo.uid,UserInfoManager.shared.userInfo.uid,"i",buildVersion,appVersion,"apple",uuid,CNLiveMCEnvironmentManager.shared.appId,sidSignStr!,UserInfoManager.shared.userInfo.token])
        var i = 0
        for paraStr in paraArr{
            let tempStr = paraStr as! String
            let paramStr = "&".appending(tempStr)
            let paramStr2 = "?".appending(tempStr)

            if str.contains(paramStr){
                //包含则替换 &sid=
                let lastStr = str.components(separatedBy: tempStr).last
                let lastSeparatedStr = (lastStr?.components(separatedBy: "&").first)!
                let oldStr = tempStr.appending(lastSeparatedStr)
                let tempValueStr = tempStr.appending(valueArr[i] as! String)
                str = str.replacingOccurrences(of: oldStr, with: tempValueStr)
            }else if str.contains(paramStr2){
                //包含则替换 &sid=
                let lastStr = str.components(separatedBy: tempStr).last
                let lastSeparatedStr = (lastStr?.components(separatedBy: "&").first)!
                let oldStr = tempStr.appending(lastSeparatedStr)
                let tempValueStr = tempStr.appending(valueArr[i] as! String)
                str = str.replacingOccurrences(of: oldStr, with: tempValueStr)
            }else{
                //不包含则拼接
                str = String(format: "%@&%@%@", str,tempStr,valueArr[i] as! String)
            }
            i = i + 1
        }
        return str
    }
    
    // MARK: - WKWebViewDelegate
    // 页面开始加载时调用
    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        print("didStartProvisionalNavigation")
    }
    // 当内容开始返回时调用
    func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
        print("didCommit")
    }
        
    // 页面加载完成之后调用
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        print("didFinish")
        self.webControllerUpdateNavBlock?(true, webView.title!, false , "")
    }
    // 页面加载失败时调用
    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        print("didFailProvisionalNavigation")
    }
    // 接收到服务器跳转请求之后调用
    func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) {
        print("didReceiveServerRedirectForProvisionalNavigation")
    }
    // 在收到响应后,决定是否跳转 -> 默认允许
    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
        
        print("decidePolicyFornavigationResponse")
                
        //允许跳转
        decisionHandler(.allow)
    }
    // 在发送请求之前,决定是否跳转 -> 默认允许
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        print("decidePolicyFornavigationAction")
        
        var urlStr = (navigationAction.request.url?.absoluteString)!
                
        if navigationAction.request.url?.host == WjjH5 {
            self.webControllerUpdateNavBlock?(false, "", true , urlStr)

            urlStr = self.checkURLWithStr(urlStr: urlStr)
            self.currentUrl = urlStr
        }
        
        if navigationAction.navigationType == .other{
            //跳转Appstore
            let url = URL(string: "https://apps.apple.com/cn/app/%E7%BD%91%E5%AE%B6%E5%AE%B6%E5%95%86%E5%AE%B6%E7%89%88/id1337575497")
            if url == navigationAction.request.url {
                if UIApplication.shared.canOpenURL(url!) { UIApplication.shared.open(url!, options: [:], completionHandler: nil)
                }
            }
        }else if navigationAction.navigationType == .linkActivated{
            let webVC =  CNWebViewController()
            webVC.url = URL(string: urlStr)
            navigationViewController().pushViewController(webVC, animated: true)
            decisionHandler(.cancel)
            return
        }
        
        decisionHandler(.allow)
    }
}