Swift WKWebview与JS互调

2021-11-09  本文已影响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
    至于第二种方式,前端写了这种方法只能也去实现。
上一篇下一篇

猜你喜欢

热点阅读