Javascript从UIWebView调用Swift

时间:2016-11-23 10:01:54

标签: javascript swift uiwebview ios10

我正在尝试从UIWebView中的javascript函数调用到iOS 10中的Swift。我已经设置了一个非常基本的项目,试图让它工作,代码如下。

import UIKit

class ViewController: UIViewController, UIWebViewDelegate  {    
  @IBOutlet var webView: UIWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let url = Bundle.main.url(forResource: "products", withExtension: "html")
        let request = NSURLRequest(url: url! as URL)
        webView.loadRequest(request as URLRequest)
    }

    @IBAction func closeDocumentViewer() {
        displayView.isHidden = true;
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

如果我只是一个从javascript函数接收一个字符串,我将不得不添加到上面?

3 个答案:

答案 0 :(得分:15)

我建议使用UIWebView代替import WebKit class ViewController: UIViewController, WKScriptMessageHandler { var webView: WKWebView? override func loadView() { super.loadView() webView = WKWebView(frame: self.view.frame) webView?.configuration.userContentController.add(self, name: "scriptHandler") self.view.addSubview(webView!) } public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { print("Message received: \(message.name) with body: \(message.body)") } // rest of code } 。然后,您将不需要注册自定义URL方案。此外,UIWebView已经过时,WKWebView具有很多优势,最显着的是性能和渲染,因为它在一个单独的过程中运行。

链接到Apple文档并建议使用WKWebView https://developer.apple.com/reference/webkit/wkwebview/

  

重要

     

从iOS 8.0和OS X 10.10开始,使用WKWebView将web内容添加到>应用程序。不要使用UIWebView或WebView。

也就是说,设置本机到javascript桥非常简单:

window.webkit.messageHandlers["scriptHandler"].postMessage("hello");

然后在您的javascript代码中,将其命名为:

    webView = WKWebView(frame: self.view.frame)
    let commander = SwiftBridgeCommander(webView!)

    commander.add("echo") {
        command in
        command.send(args: "You said: \(command.args)")
    }

我编写了一个利用它的库,并添加了一些奇特的javascript语法。 https://github.com/tmarkovski/BridgeCommander

要使用它,只需引用项目(或将swift和javascript文件添加到Xcode项目中)并调用

var commander = new SwiftBridgeCommander();
commander.call("echo", "Hello", function(args) {
        // success callback
    }, function(error) { 
        // error callback
});

然后你就可以在这样的javascript中使用回调语法

{{1}}

答案 1 :(得分:3)

您必须使用自定义URL Scheme,例如myawesomeapp,并使用以下内容拦截对它的请求:

func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool

使用window.location=myawesomeapp://hello=world触发对本机代码的调用,并获取您在本机代码中从request.URL.query传递的查询参数。

有关详细信息,请参阅我在此处UIWebView的问题:JavaScript synchronous native communication to WKWebView

答案 2 :(得分:0)

我们可以借助 WKScriptMessageHandler

从Javascript调用swift函数

符合WKScriptMessageHandler协议的类提供了一种从运行在网页上的JavaScript接收消息的方法。

我们需要将事件监听器添加到WKUserContentController

 let contentController = WKUserContentController()
    contentController.add(self, name: "loginAction”)

我们必须实现其userContentController来接收从Javascript发送的内容。对于前。仅限于我们现在想要的“登出”。

  func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {       
       if message.name == "logout" {
           print("JavaScript is sending a message \(message.body)")
       }
   }

从JavaScript端开始,他们必须像这样实现:

 function sendLogoutAction() {
       try {
           webkit.messageHandlers.logout.postMessage("logout");
       } catch(err) {
           console.log('The native context does not exist yet');
       }
    }