Swift webview:如何从 javascript 正确调用 swift 代码?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25827368/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Swift webview: How to call correctly swift code from javascript?
提问by adam
I'm trying to make my javascript interact with swift code but unfortunately i didn't succeed.
我试图让我的 javascript 与 swift 代码交互,但不幸的是我没有成功。
For the moment, i just tried to change the headers colors and display a message like you will see in the code below.
目前,我只是尝试更改标题颜色并显示一条消息,就像您在下面的代码中看到的那样。
Here's my (index.html) code:
这是我的(index.html)代码:
<!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>
Here's my (main.js -JavaScript) code:
这是我的(main.js -JavaScript)代码:
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";
}
Here's my (ViewController.swift) code:
这是我的(ViewController.swift)代码:
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.
}
}
采纳答案by Nate Cook
You have everything set up properly, but you aren't giving your WKWebViewConfigurationinstance to the WKWebView. Since the configuration has the details of the Javascript/Swift bridge, you can't talk back and forth.
您已经正确设置了所有内容,但是您没有将您的WKWebViewConfiguration实例提供给WKWebView. 由于配置中有 Javascript/Swift 桥接的细节,你不能来回说。
override func loadView() {
// ...
var config = WKWebViewConfiguration()
config.userContentController = contentController
self.webView = WKWebView(frame: self.view.frame, configuration: config)
self.view = self.webView!
}
回答by BananaAcid
my 2 cents, using a javascript callback with JSON ... for full class definition and layout, refer to adam's code
我的 2 美分,使用带有 JSON 的 javascript 回调......有关完整的类定义和布局,请参阅 adam 的代码
import UIKit
import WebKit
class ViewController: UIViewController, WKScriptMessageHandler {
var webView: WKWebView?
...
then
然后
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
}
and specifically
特别是
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) {}
}
}

