Swift webview: comment appeler correctement le code swift à partir de javascript?

j'essaie de faire interagir mon javascript avec le code swift, mais malheureusement je n'ai pas réussi.

pour le moment, j'ai juste essayé de changer les couleurs des en-têtes et d'afficher un message comme vous le verrez dans le code ci-dessous.

Voici mon ( index.html) code:

<!DOCTYPE html>
<html>
    <head>
        <title>Test</title>
        <meta charset="UTF-8">
    </head>
    <body>
        <h1>WebView Test</h1>
        <script type="text/javascript" src="main.js"></script>
    </body>
</html>

Voici mon ( main.JS-JavaScript) code:

function callNativeApp () {
    try {
        webkit.messageHandlers.callbackHandler.postMessage("Send from JavaScript");
    } catch(err) {
        console.log('error');
    }
}

setTimeout(function () {
    callNativeApp();
}, 5000);

function redHeader() {
    document.querySelector('h1').style.color = "red";
}

Voici mon (ViewController.swift) code:

import UIKit
import WebKit

class ViewController: UIViewController, WKScriptMessageHandler {

    @IBOutlet var containerView : UIView! = nil

    var webView: WKWebView?

    override func loadView() {
        super.loadView()

        var contentController = WKUserContentController();
        var userScript = WKUserScript(
            source: "redHeader()",
            injectionTime: WKUserScriptInjectionTime.AtDocumentEnd,
            forMainFrameOnly: true
        )
        contentController.addUserScript(userScript)
        contentController.addScriptMessageHandler(
            self,
            name: "callbackHandler"
        )

        var config = WKWebViewConfiguration()
        config.userContentController = contentController

        self.webView = WKWebView()
        self.view = self.webView!
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        var url = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("index", ofType: "html")!)
        var req = NSURLRequest(URL: url)
        self.webView!.loadRequest(req)
    }

    func userContentController(userContentController: WKUserContentController!,didReceiveScriptMessage message: WKScriptMessage!) {
            if(message.name == "callbackHandler") {
            println("JavaScript is sending a message (message.body)")
            } }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}
20
demandé sur adam 2014-09-14 00:27:06

2 réponses

vous avez tout mis en place correctement, mais vous ne donnez pas votre WKWebViewConfiguration exemple WKWebView. Étant donné que la configuration contient les détails du pont Javascript/Swift, vous ne pouvez pas faire de va-et-vient.

override func loadView() {
    // ...
    var config = WKWebViewConfiguration()
    config.userContentController = contentController

    self.webView = WKWebView(frame: self.view.frame, configuration: config)
    self.view = self.webView!
}
14
répondu Nate Cook 2014-09-14 05:15:56

mes 2 cents, à l'aide d'un javascript de rappel avec JSON ... pour la définition complète de la classe et la mise en page, reportez-vous au Code d'adam

import UIKit
import WebKit

class ViewController: UIViewController, WKScriptMessageHandler {
    var webView: WKWebView?
    ...

override func loadView() {
    let theConfiguration = WKWebViewConfiguration()
    let contentController = theConfiguration.userContentController

    // alert fix, at start to allow a JS script to overwrite it
    contentController.addUserScript( WKUserScript(
        source: "window.alert = function(message){window.webkit.messageHandlers.messageBox.postMessage({message:message});};",
        injectionTime: WKUserScriptInjectionTime.AtDocumentStart,
        forMainFrameOnly: true
    ) )
    contentController.addScriptMessageHandler(self, name: "messageBox")

    self.webView = WKWebView(frame: self.view.frame, configuration: theConfiguration)

    // and here things like: self.webView!.navigationDelegate = self
    self.view = self.webView!  // fill controllers view
}

et plus précisément

func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {

    if message.name == "messageBox" {
        let sentData = message.body as! Dictionary<String, String>

        let message:String? = sentData["message"]

        let alertController = UIAlertController(title: nil, message: message, preferredStyle: UIAlertControllerStyle.Alert)
        alertController.addAction(UIAlertAction(title: NSLocalizedString("OK", comment:"btnOK"), style: .Default, handler: nil))
        self.presentViewController(alertController, animated: true) {}
    }
}
1
répondu BananaAcid 2015-12-21 16:43:17