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.
}
}
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!
}
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) {}
}
}