swift中WKWebView和JS交互实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/I123456789T/article/details/89175201

在Swift中加载HTML网页有两个view,分别是WKWebView和UIWebView,这里我使用的是WKWebView

这里分享一下我的写法:

1、定义变量WKWebView:

lazy var webView: WKWebView = {
        ///偏好设置
        let preferences = WKPreferences()
        preferences.javaScriptEnabled = true
    
        let configuration = WKWebViewConfiguration()
        configuration.preferences = preferences
        configuration.selectionGranularity = WKSelectionGranularity.character
        configuration.userContentController = WKUserContentController()
        // 给webview与swift交互起名字,webview给swift发消息的时候会用到
        configuration.userContentController.add(WeakScriptMessageDelegate(self), name: "logger")
        configuration.userContentController.add(WeakScriptMessageDelegate(self), name: "myPosition")
        configuration.userContentController.add(WeakScriptMessageDelegate(self), name: "getRegistionId")
        configuration.userContentController.add(WeakScriptMessageDelegate(self), name: "getUserInfo")
        configuration.userContentController.add(WeakScriptMessageDelegate(self), name: "saveUserInfo")
        configuration.userContentController.add(WeakScriptMessageDelegate(self), name: "scanCode")
        configuration.userContentController.add(WeakScriptMessageDelegate(self), name: "alertl")
        
        var webView = WKWebView(frame: CGRect(x: 0,
                                              y: 44,
                                              width: UIScreen.main.bounds.width,
                                              height: UIScreen.main.bounds.height-20),
                                configuration: configuration)
        // 让webview翻动有回弹效果
        webView.scrollView.bounces = false
        // 只允许webview上下滚动
        webView.scrollView.alwaysBounceVertical = true
        webView.navigationDelegate = self
        //自定义userAgent,用于在浏览器中判断是否在app打开
        webView.customUserAgent = "iosApp"
        
        return webView
    }()

注意,此加载网页的视图控制器需要实现这两个协议:WKNavigationDelegate,WKScriptMessageHandler

注:这里说明一下这行代码:configuration.userContentController.add(WeakScriptMessageDelegate(self), name: "logger")

configuration在上面代码区域可以看到,是定义的一个WKWebViewConfiguration() ,

然后调用它的userContentController.add() ,这里简单说明一下参数:第一个参数位置WeakScriptMessageDelegate协议,这里是固定写法,

主要看第二个参数name,name的值需要注意,它是一个字符串,就是我们在js中需要通过这个name,然后点上swift中原生的方法完成交互功能,js中所有需要需要调用swift原生方法的语句,都需要在swift中定义一个对月的name,

下面介绍如何在swift中处理js调用原生方法时判断调用的是哪一个方法,判断方法也是通过上面定义的name去区分,可以携带参数:

要重写下面的这个函数:userContentController ,注意参数

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        ///接收js调用方法
        
            ///在控制台中打印html中console.log的内容,方便调试
            let body = message.body
            print("--------js交互了------------")
            if message.name == "logger" {
                print("JS Log \(body)")
                EWToast.showBottomWithText(text: "JS Log: \(body)")
                return
            }
            
            ///message.name是约定好的方法名,message.body是携带的参数
            switch message.name {
                
            case "myPosition":
                ///不接收参数时直接不处理message.body即可,不用管Html传了什么
                self.myDistance()
                
            case "getRegistionId":
                
                self.getRegistId()
                
            case "getUserInfo":
                
                self.getUserInfo()
                
            case "saveUserInfo":
                
                self.saveInfo(array: message.body as! [AnyObject])
                
            case "scanCode":
                // 打开相机
                self.openCemera()
                
            case "alertl":
                //这个项目中单独的Toast提示
                EWToast.showBottomWithText(text: "触发成功")
                
            default:
                break
            }
        
    }

仔细一看,每一个case 判断的字符串就是上面我们定义的name,在js中调用时,它会自动根据你调用原生方法时用的是哪一个,他就会走对应的判断,然后在case中我们就可以调用原生的方法了,

在js向原生传递参数时,可以传递数组,这里我用的是数组传递,没看到单个数据怎么传递的,

写法:window.webkit.messageHandlers.saveUserInfo.postMessage(["abcd",1]) 

注意代码标红的就是我们在swift中定义的name,后面的postMessage这个随意,看你想做什么用就写什么,没什么特殊要求,这里是传递消息,主要是参数,我用数组,传递不一样的数据类型也可以,

在swift中接收参数可以看到 我是这么写的:self.saveInfos(array: message.body as! [AnyObject])  

这样就可以了!去试试吧!

在多说一句:原生调用js方法: 

webView.evaluateJavaScript("setToken('\(token ?? "")')", completionHandler: nil)

setToken是js提供的function函数如:

function setToken(token){
          //操作 
}

猜你喜欢

转载自blog.csdn.net/I123456789T/article/details/89175201