从使用 wkwebview 返回值的 javascript 调用 swift 函数

Posted

技术标签:

【中文标题】从使用 wkwebview 返回值的 javascript 调用 swift 函数【英文标题】:Call a swift function from java script that returns a value using wk webview 【发布时间】:2016-09-22 07:34:29 【问题描述】:

我想从 java 脚本代码中调用一个 swift 函数,它将 device id 返回到脚本,我已经添加了当前使用的代码。请告知如何从 swift 函数将值返回给java script,提前致谢

代码片段:

     super.viewDidLoad()
    
    self.webView = WKWebView()
    let preferences = WKPreferences()
    preferences.javascriptEnabled = true
    let configuration = WKWebViewConfiguration()
    configuration.preferences = preferences
    configuration.userContentController = contentController
    configuration.userContentController.addScriptMessageHandler(self,name: "interOp")
    self.webView = WKWebView(frame: self.view.frame, configuration: configuration)
    print(self.view.frame)
    self.view = self.webView
    webView!.navigationDelegate = self
    let url = NSURL(string:"http://softence.com/devTest/vb_ios.html")
    let req = NSURLRequest(URL:url!)
    self.webView!.loadRequest(req)

    

// did receivescript message is working fine
func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage)

    let sentData = message.body as! NSDictionary
    print(sentData)
    if sentData["name"] as! String == "DeviceInfo"
    
        self.DeviceInfo()
    

// i want to return the following device info to javascript
func DeviceInfo() -> String

let dict = NSMutableDictionary()
    dict.setValue(UIDevice.currentDevice().model, forKey: "model")
    dict.setValue(UIDevice.currentDevice().name, forKey: "name")
    dict.setValue(UIDevice.currentDevice().systemVersion, forKey: "system_version")
    return String(dict)

【问题讨论】:

仅供参考 JavaScript 是一个词... ;) 您可以使用this 回答,以防您必须以同步方式进行。 【参考方案1】:

尝试查看WKWebView 上的evaluateJavaScript(_:, completionHandler:) 函数,如here 所述

要使用它,您的 DeviceInfo 函数应该定义 您想要执行的完整 JavaScript 字符串

例如,如果你有一个这样定义的 JavaScript 函数:

showDeviceInfo(model, name, system_version) 


那么你的DeviceInfo 函数可能看起来像这样:

func deviceInfo() 
    let model = UIDevice.currentDevice().model
    let name = UIDevice.currentDevice().name
    let systemVersion = UIDevice.currentDevice().systemVersion

    let javaScriptString = "showDeviceInfo(\(model), \(name), \(systemVersion));" //string your JavaScript string together from the previous info...and no...it aint pretty :)
    webView.evaluateJavaScript(javaScriptString, completionHandler: nil)

您也可以从您的DeviceInfo 函数中返回javaScriptString,然后在您的userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) 中调用它,重要的是:

    您需要定义要执行的整个 JavaScript 字符串 您需要拨打evaluateJavaScript

希望对你有所帮助。

【讨论】:

您好,感谢您的回复...我尝试通过 evaluateJavaScript 方法发送一个简单的字符串,但没有任何反应,并在网页中显示“未定义”。而且我不想发送数据,java脚本必须自动调用swift函数并获取swift函数@pbodsk返回的值 您发送的字符串是什么样的?它必须是有效的 JavaScript。关于“JavaScript 必须自动调用 swift 函数”,不是吗?您从调用 didReceiveScriptMessage 的 JavaScript 调用 Swift 函数。这再次调用deviceInfo(),它将生成一个 JavaScript 字符串,该字符串调用您的 JavaScript 函数,并填充正确的数据。还是我误解了你的意思?希望我说得通 是的,你是对的,我问的是我们是否可以直接从 java 脚本代码调用 swift 函数,而无需像在 android 中那样向 swift 代码发送消息。 据我了解,您不能,您必须使用WKUserContentController 作为 JavaScript 代码和本机代码之间的桥梁,正如您在上面的示例中设置的那样。一旦您调用了WKUserContentController 检测到的window.webkit.messageHandlers.interOp.postMessage(someDataHere);,并且调用了didReceiveScriptMessage,您就可以准确地确定调用了哪个JavaScript 函数。要以其他方式发送数据,您可以使用我在上面尝试描述的方法 看看这篇文章:priyaontech.com/2014/12/native-–-js-bridging-on-ios8-using-wkwebview/ 或者这个nshipster.com/wkwebkit希望他们能帮助你了解发生了什么:)

以上是关于从使用 wkwebview 返回值的 javascript 调用 swift 函数的主要内容,如果未能解决你的问题,请参考以下文章

如何从 WKWebview 内的按钮单击重定向并使用目标 c 返回到 iOS 应用程序?

WKWebview 的 javascript 调用返回 nil

从 iOS Swift 中的 cam 扫描仪 SDK 返回时,WKwebview 是空白屏幕?

WKWebView evaluateJavaScript 不返回 html

WKWebView 从 HTTP 请求中注入 cookie

使用wkwebview时,push后,再pop返回,报错