我正在尝试建立Swift-JavaScript通信。这是我在HTML和JS中的设置:
<!DOCTYPE HTML>
<html>
<head>
<title> My Page </title>
<script type="text/javascript" src="myscript.js"></script>
</head>
<body>
<h1 id="title"> SWIFT-JavaScript (SJS) Communication </h1>
<p> Press the button below to establish WebView Communication</p>
<input type="button" value="click" onclick="isPressed()"/>
</body>
</html>
function isPressed() {
window.location = "mike://stuff"; //set password
//Print a message on SWIFT CONSOLE
window.webkit.messageHandlers.SJS_COMMUNICATION.postMessage("JavaScript >> JS said hello !");
}
function foo() {
alert("sa");
window.webkit.messageHandlers.SJS_COMMUNICATION.postMessage("JavaScript >> *****************");
window.webkit.messageHandlers.SJS_COMMUNICATION.postMessage("JavaScript >> * SUCCESS *");
window.webkit.messageHandlers.SJS_COMMUNICATION.postMessage("JavaScript >> *****************");
//pass some parameters here
}
这是我在SWIFT中的第一个项目,所以我试图理解许多概念。我的目标是:
1。从SWIFT执行一些JavaScript函数(即函数foo(){...};)
2。从JavaScript执行一些SWIFT函数
这是我的ViewController.swift
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandler {
//Declare the actual WebKit WebView
@IBOutlet weak var webView: WKWebView!
var SJS_check:Bool = false //Check if the WKWebView has been created succesufully
override func loadView() {
//Declare SWIFT & JavaScript Message Handler add prepare the configuration
print(" SWIFT >> Creating configuration: SJS_COMMUNICATION")
let controller = WKUserContentController()
let configuration = WKWebViewConfiguration()
controller.add(self, name: "SJS_COMMUNICATION")
configuration.userContentController = controller
//Add the SJS_COMMUNICATION configuration on the WebView
webView = WKWebView(frame: .zero, configuration: configuration)
webView.navigationDelegate = self
view = webView
self.webView.clipsToBounds = true
SJS_check = true //loadView was succesful - allow viewDidLoad() to execute
print(" SWIFT >> WKWebView with SJS_COMMUNICATION has been created")
}
// Do any additional setup after loading the view, typically from a nib.
override func viewDidLoad() {
super.viewDidLoad()
//Check if WKWebView was successful in loadView()
if(SJS_check == true){
print(" SWIFT >> Establishing URL connection")
//CHECK URL CONNECTION: open file = "web/index.html"
if let thisURL = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "web") {
let fragURL = NSURL(string: "#FRAG_URL", relativeTo: thisURL)!
let URL_request = NSURLRequest(url: fragURL as URL)
webView.load(URL_request as URLRequest) //Load the Request on the WebView
//Allow SWIFT to read the component of HTML, CSS, JS
webView.loadFileURL(thisURL, allowingReadAccessTo: thisURL.deletingLastPathComponent())
print(" SWIFT >> URL connection was successful!")
}else{
print(" SWIFT >> *ERROR* URL connection has failed!")
}
}else{ //if SJS_check == false
print(" SWIFT >> *ERROR* WKWebView has not been created!")
}
}
//Passes a message from JavaScript and displays it on SWIFT console
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
print("\(message.body)")
}
/*
func webView(_ webView: WKWebView, JS_REQUEST request: NSURLRequest, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
print("it works")
if let host = request.url?.host {
if host == "mike" {
print(" SWIFT >> CONNECTED TO: mike://stuff")
decisionHandler(.allow)
return
}else{
print(" SWIFT >> *ERROR* host mike NOT FOUND!")
}
}else{
print(" SWIFT >> *ERROR* navigationAction.request.url?.host FAILED!")
}
decisionHandler(.cancel)
}
*/
func webView(_ webView: WKWebView, JS_Request message: String, initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping () -> Void) {
print("helloWorld!!!!????")
}
/*
//Pass parameters from JavaScript to SWIFT
func webView(_ webView: WKWebView, JS_REQUEST request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
print("DELETE 7")
print("DELETE///// \(request)")
//Check if the scheme of request.url.scheme exist
if let scheme = request.url?.scheme {
//Check if scheme = with mike
if scheme == "mike"{
webView.evaluateJavaScript("foo()", completionHandler: { (result, error) in
if let thisResult = result{
NSLog(" SWIFT >> path FOUND == \(thisResult)")
}
})
//check if function exist in JavaScript
var thisFunction = "foo()"
if let result = webView.stringByEvaluatingJavaScript("foo()") {
NSLog(" SWIFT >> Searching for Javascript function named \(thisFunction) - *** SUCCESSFUL OPERATION *** ")
}
}else{
NSLog(" SWIFT >> path \(scheme) - !!!! NOT FOUND !!!!")
}
}else{
NSLog(" SWIFT >> scheme - !!!! NOT FOUND !!!!")
}
return true
}
*/
}
输出(SWIFT控制台):
"
SWIFT >> Creating configuration: SJS_COMMUNICATION
2020-05-14 15:33:25.766547+0100 js_4[945:27776] [MC] Lazy loading NSBundle MobileCoreServices.framework
2020-05-14 15:33:25.768178+0100 js_4[945:27776] [MC] Loaded MobileCoreServices.framework
SWIFT >> WKWebView with SJS_COMMUNICATION has been created
SWIFT >> Establishing URL connection
SWIFT >> URL connection was successful!
"
问题:
除SWIFT代码中的webView()函数外,其他一切看起来都可以正常工作。我尝试了代码中列出的所有三个webView Function,但似乎都没有用。实际上,我认为func webView(..){}
根本不执行。
我的假设是,它与UIDelegate
,NavigationDelegate
和/或WKUIDelegate
有关。
我在我的应用中执行相同的操作,并使它正常工作。看来您已经正确设置了基础知识。我所看到的和所做的事情之间唯一的真正区别是,创建一个WKWebViewConfiguration,然后创建WKWebView,然后调用webView.configuration.userContentController.add()。我也没有手动创建WKUserContentController,我只使用WKWebViewConfiguration附带的那个。
let configuration = WKWebViewConfiguration()
let webView = WKWebView(frame: .zero, configuration: configuration)
webView.configuration.userContentController.add(self, name: "MessageHandler")
尝试这种事件排序,看看是否有帮助?