美文网首页
Swift WKWebview与JS互调

Swift WKWebview与JS互调

作者: 丹学徒 | 来源:发表于2021-11-09 16:52 被阅读0次

    项目需求:

    一. js调用app方法并同步返回值

    js端调用方式:

    let res = test("helloworld")
    

    js端的关键代码:

    let params = JSON.stringify(params)
    let data = {
      "method": method, // 传入test
      "params": params // 传入helloworld
    }
    // 使用prompt方法传递参数
    let res = prompt(JSON.stringify(data))
    return res
    

    swift端的代码:

    // 1.注册 这种注册是有返回值
    webview.configuration.userContentController.addScriptMessageHandler(self, contentWorld: .page, name: "test")
    // 2.继承 WKScriptMessageHandlerWithReply 类
    extension WebViewController: WKScriptMessageHandler, WKScriptMessageHandlerWithReply{
        
        /// prompt方式  对应js调用prompt("test")
        func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
            let jsonObj = JSON.init(parseJSON: prompt)
            let method = jsonObj["method"].stringValue
            let params = jsonObj["params"].stringValue
            print(method)
            if method == "test" {
                let result = self.test(params)
                // result就是返回的值
                completionHandler(result)
            }
            else {
                completionHandler("")
            }
        }
    }
    
    二. js调用app方法,使用Promise风格返回值

    js端调用方式:.then方式

    test("helloworld").then(res=>{
        console.log("promise ",res)
    })
    

    js端的代码:(伪代码)

    return new Promise((resolve, reject) => {
        if (this.brower() === 'android') {
            ...
        } else if (this.brower() === 'ios') {
           if (window.webkit !== undefined) {
               params = JSON.stringify(params)
               // method是字符串参数
               let res = window.webkit.messageHandlers[method]['postMessage'](params)
               resolve(res)
           }  else { reject('40001')}
    }
        
    

    swift端的代码:

    // 1.注册 这种注册是有返回值
    webview.configuration.userContentController.addScriptMessageHandler(self, contentWorld: .page, name: "test")
    // 2.继承 WKScriptMessageHandlerWithReply 类
    /// 返回值Handle 可对接js的Promise风格 .then返回的值
        func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage, replyHandler: @escaping (Any?, String?) -> Void) {
            print("传来的方法为", message.name)
            print("传来的参数为", message.body)
            if message.name == "test" {
                let result = self.test(message.body)
                replyHandler(result, nil) // first var is success return val, second is err string if error
            }
        }
    
    三. js调用app方法,用app回调js的方法去返回值

    js端调用方式:

    test({
        params: “helloworld”,
        success: res=>{
               console.log("test",res)
        }
    })
    

    js端的关键代码:

    test(params) {
      window['TestSuccess'] = params.success
      // ...省略调用app的方法了
    }
    

    swift端的代码:

    // 1.注册 这种注册无返回值
    webview.configuration.userContentController.add(self, name: "test")
    // 2.继承 WKScriptMessageHandler 类
        func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage, replyHandler: @escaping (Any?, String?) -> Void) {
            print("传来的方法为", message.name)
            print("传来的参数为", message.body)
            if message.name == "test" {
                let strRes = self.test(message.body)
                // 成功采用回调js方法
               webview.evaluateJavaScript("TestSuccess(\(strRes))") { (jsmessage, err)  in
                    print("成功回调\(String(describing: jsmessage)),\(String(describing: err))")
                }
            }
        }
    
    总结:
    1. 同步返回值 用第一种方法
    2. 异步返回值 用第三种方法 app回调js方法
    3. 没有返回值 就不回调js
      至于第二种方式,前端写了这种方法只能也去实现。

    相关文章

      网友评论

          本文标题:Swift WKWebview与JS互调

          本文链接:https://www.haomeiwen.com/subject/egamzltx.html