Javascript 从 UIWebView 调用 Swift
Javascript call to Swift from UIWebView
我正在尝试从 UIWebView 中的 javascript 函数调用 iOS 中的 Swift 10。我已经设置了一个非常基本的项目来尝试获取这个工作,代码如下。
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 函数接收一个字符串,我需要在上面添加什么?
您必须自定义 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
我建议考虑使用 WKWebView
而不是 UIWebView
。然后您将不需要注册自定义 URL 方案。此外,UIWebView 已过时,而 WKWebView 有很多优势,最显着的是性能和渲染,因为它在单独的进程中运行。
Link Apple 文档和使用 WKWebView 的建议
https://developer.apple.com/reference/webkit/wkwebview/
Important
Starting in iOS 8.0 and OS X 10.10, use WKWebView to add web content to your > app. Do not use UIWebView or WebView.
就是说,设置本地到 javascript 桥接非常简单:
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
}
然后在您的 javascript 代码中调用它:
window.webkit.messageHandlers["scriptHandler"].postMessage("hello");
我编写了一个库来利用它并添加了一些奇特的 javascript 语法。
https://github.com/tmarkovski/BridgeCommander
要使用它,只需引用项目(或将 swift 和 javascript 文件添加到您的 Xcode 项目)并调用
webView = WKWebView(frame: self.view.frame)
let commander = SwiftBridgeCommander(webView!)
commander.add("echo") {
command in
command.send(args: "You said: \(command.args)")
}
然后您将能够像这样在 javascript 中使用回调语法
var commander = new SwiftBridgeCommander();
commander.call("echo", "Hello", function(args) {
// success callback
}, function(error) {
// error callback
});
我们可以在 WKScriptMessageHandler
的帮助下从 Javascript 调用 swift 函数
一个符合WKScriptMessageHandler协议的class提供了一种在网页上接收JavaScript运行消息的方法
我们需要在我们的 WKUserContentController 中添加一个事件监听器
let contentController = WKUserContentController()
contentController.add(self, name: "loginAction”)
我们必须实现它的 userContentController 来接收从 Javascript 发送的内容。例如。仅限于我们现在想要的 "logout"。
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');
}
}
我正在尝试从 UIWebView 中的 javascript 函数调用 iOS 中的 Swift 10。我已经设置了一个非常基本的项目来尝试获取这个工作,代码如下。
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 函数接收一个字符串,我需要在上面添加什么?
您必须自定义 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
我建议考虑使用 WKWebView
而不是 UIWebView
。然后您将不需要注册自定义 URL 方案。此外,UIWebView 已过时,而 WKWebView 有很多优势,最显着的是性能和渲染,因为它在单独的进程中运行。
Link Apple 文档和使用 WKWebView 的建议 https://developer.apple.com/reference/webkit/wkwebview/
Important
Starting in iOS 8.0 and OS X 10.10, use WKWebView to add web content to your > app. Do not use UIWebView or WebView.
就是说,设置本地到 javascript 桥接非常简单:
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
}
然后在您的 javascript 代码中调用它:
window.webkit.messageHandlers["scriptHandler"].postMessage("hello");
我编写了一个库来利用它并添加了一些奇特的 javascript 语法。 https://github.com/tmarkovski/BridgeCommander
要使用它,只需引用项目(或将 swift 和 javascript 文件添加到您的 Xcode 项目)并调用
webView = WKWebView(frame: self.view.frame)
let commander = SwiftBridgeCommander(webView!)
commander.add("echo") {
command in
command.send(args: "You said: \(command.args)")
}
然后您将能够像这样在 javascript 中使用回调语法
var commander = new SwiftBridgeCommander();
commander.call("echo", "Hello", function(args) {
// success callback
}, function(error) {
// error callback
});
我们可以在 WKScriptMessageHandler
的帮助下从 Javascript 调用 swift 函数一个符合WKScriptMessageHandler协议的class提供了一种在网页上接收JavaScript运行消息的方法
我们需要在我们的 WKUserContentController 中添加一个事件监听器
let contentController = WKUserContentController()
contentController.add(self, name: "loginAction”)
我们必须实现它的 userContentController 来接收从 Javascript 发送的内容。例如。仅限于我们现在想要的 "logout"。
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');
}
}