让 invokeUndefinedMethodFromWebScript 在 Swift 中工作
Getting invokeUndefinedMethodFromWebScript to work in Swift
我正在尝试让 Javascript-Swift 界面与 WKWebView 一起工作,似乎有人已经让它工作了 here。
但是我无法让它在 Swift 中工作(我是 Swift 的新手,也是 Obj-C 的新手)。我在 ViewController.swift 中尝试了以下代码,并将 WKWebView 添加到 Main.storyboard 并连接:
import WebKit
class ViewController: NSViewController, WKUIDelegate {
@IBOutlet weak var wkWebView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "http://127.0.0.1:8080")
let request = URLRequest(url: url!)
wkWebView!.configuration.preferences.javaScriptEnabled = true
wkWebView!.load(request)
}
}
extension WKWebView {
open override func invokeUndefinedMethod(fromWebScript name: String!, withArguments arguments: [Any]!) -> Any! {
return "Hello From Swift"
}
}
HTML 一侧:
<html>
<body>
<p>Hello World</p>
<input type=text id='i'/>
<input type=button value='Submit' onclick='document.getElementById(\"i\").value = window.external.MY_ObjectiveCFunction();'>
</body>
</html>
但是当我点击提交按钮时没有任何反应。如果我使用 document.getElementById("i") = "hello"
,它仍然有效。 @ctrlspace 似乎以某种方式让它工作(参见上面的 link)。
有什么想法吗?
您找到了一篇旧文章,该文章是为古老的 WebView
macOS 而写的,而不是 WKWebView
。
当使用 WKWebView
时,您使用 WKScriptMessageHandler
在 JavaScript 和 Swift 之间进行交互。
ViewController.swift:
import WebKit
class ViewController: NSViewController, WKUIDelegate {
@IBOutlet weak var wkWebView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let url = Bundle.main.url(forResource: "index", withExtension: "html")! //Simplified for testing
let request = URLRequest(url: url)
wkWebView.configuration.preferences.javaScriptEnabled = true
wkWebView.configuration.userContentController.add(self, name: "mySwiftMessage") //<-
wkWebView.load(request)
}
//...
}
extension ViewController: WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
switch message.name {
case "mySwiftMessage":
if let callbackName = message.body as? String {
message.webView?.evaluateJavaScript("\(callbackName)('Hello From Swift');", completionHandler: nil)
}
default:
break
}
}
}
index.html:
<html>
<body>
<script>
function myCallback(value) {
document.getElementById("i").value = value;
}
</script>
<p>Hello World</p>
<input type=text id='i'/>
<input type=button value='Submit' onclick='window.webkit.messageHandlers.mySwiftMessage.postMessage("myCallback");'>
</body>
</html>
添加
要使 WKWebView
在 iOS 之前工作于 11,您只需以编程方式实例化它:
import WebKit
class ViewController: UIViewController, WKUIDelegate {
var wkWebView: WKWebView! //<- NOT an IBOutlet
override func viewDidLoad() {
super.viewDidLoad()
let webConfig = WKWebViewConfiguration()
webConfig.preferences.javaScriptEnabled = true
webConfig.userContentController.add(self, name: "mySwiftMessage")
wkWebView = WKWebView(frame: self.view.bounds, configuration: webConfig)
view.addSubview(wkWebView)
//You may need to add some constraints...
//And create a better `index.html` for iOS...
let url = Bundle.main.url(forResource: "index", withExtension: "html")!
let request = URLRequest(url: url)
wkWebView.load(request)
}
//...
}
我正在尝试让 Javascript-Swift 界面与 WKWebView 一起工作,似乎有人已经让它工作了 here。
但是我无法让它在 Swift 中工作(我是 Swift 的新手,也是 Obj-C 的新手)。我在 ViewController.swift 中尝试了以下代码,并将 WKWebView 添加到 Main.storyboard 并连接:
import WebKit
class ViewController: NSViewController, WKUIDelegate {
@IBOutlet weak var wkWebView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "http://127.0.0.1:8080")
let request = URLRequest(url: url!)
wkWebView!.configuration.preferences.javaScriptEnabled = true
wkWebView!.load(request)
}
}
extension WKWebView {
open override func invokeUndefinedMethod(fromWebScript name: String!, withArguments arguments: [Any]!) -> Any! {
return "Hello From Swift"
}
}
HTML 一侧:
<html>
<body>
<p>Hello World</p>
<input type=text id='i'/>
<input type=button value='Submit' onclick='document.getElementById(\"i\").value = window.external.MY_ObjectiveCFunction();'>
</body>
</html>
但是当我点击提交按钮时没有任何反应。如果我使用 document.getElementById("i") = "hello"
,它仍然有效。 @ctrlspace 似乎以某种方式让它工作(参见上面的 link)。
有什么想法吗?
您找到了一篇旧文章,该文章是为古老的 WebView
macOS 而写的,而不是 WKWebView
。
当使用 WKWebView
时,您使用 WKScriptMessageHandler
在 JavaScript 和 Swift 之间进行交互。
ViewController.swift:
import WebKit
class ViewController: NSViewController, WKUIDelegate {
@IBOutlet weak var wkWebView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
let url = Bundle.main.url(forResource: "index", withExtension: "html")! //Simplified for testing
let request = URLRequest(url: url)
wkWebView.configuration.preferences.javaScriptEnabled = true
wkWebView.configuration.userContentController.add(self, name: "mySwiftMessage") //<-
wkWebView.load(request)
}
//...
}
extension ViewController: WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
switch message.name {
case "mySwiftMessage":
if let callbackName = message.body as? String {
message.webView?.evaluateJavaScript("\(callbackName)('Hello From Swift');", completionHandler: nil)
}
default:
break
}
}
}
index.html:
<html>
<body>
<script>
function myCallback(value) {
document.getElementById("i").value = value;
}
</script>
<p>Hello World</p>
<input type=text id='i'/>
<input type=button value='Submit' onclick='window.webkit.messageHandlers.mySwiftMessage.postMessage("myCallback");'>
</body>
</html>
添加
要使 WKWebView
在 iOS 之前工作于 11,您只需以编程方式实例化它:
import WebKit
class ViewController: UIViewController, WKUIDelegate {
var wkWebView: WKWebView! //<- NOT an IBOutlet
override func viewDidLoad() {
super.viewDidLoad()
let webConfig = WKWebViewConfiguration()
webConfig.preferences.javaScriptEnabled = true
webConfig.userContentController.add(self, name: "mySwiftMessage")
wkWebView = WKWebView(frame: self.view.bounds, configuration: webConfig)
view.addSubview(wkWebView)
//You may need to add some constraints...
//And create a better `index.html` for iOS...
let url = Bundle.main.url(forResource: "index", withExtension: "html")!
let request = URLRequest(url: url)
wkWebView.load(request)
}
//...
}