Swift webview:如何从 javascript 中正确调用 swift 代码?
Posted
技术标签:
【中文标题】Swift webview:如何从 javascript 中正确调用 swift 代码?【英文标题】:Swift webview: How to call correctly swift code from javascript? 【发布时间】:2014-09-13 20:27:06 【问题描述】:我正在尝试让我的 javascript 与 swift 代码交互,但不幸的是我没有成功。
目前,我只是尝试更改标题颜色并显示一条消息,如下面的代码所示。
这是我的 (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>
这是我的 (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";
这是我的 (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.
【问题讨论】:
Apple 的 loadView 文档 developer.apple.com/documentation/uikit/uiviewcontroller/… 说:“您对此方法的自定义实现不应调用 super。”这在接受的答案中可能并不明显。 【参考方案1】:您已正确设置所有内容,但您没有将您的 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!
【讨论】:
请注意在loadView()
方法中调用self.view.frame
会导致EXC_BAD_ACCESS
崩溃。
@Dev 如果是 casugin,我应该叫什么 self.view.frame EXC_BAD_ACCESS
@Dev 只有在您忘记事先调用 super.loadView() 时才会这样做
MacOS版本呢?【参考方案2】:
我的 2 美分,使用带有 JSON 的 javascript 回调...对于完整的类定义和布局,请参阅 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
特别是
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)
【讨论】:
您好,您能帮我提供一下它的 MacOS 版本吗?以上是关于Swift webview:如何从 javascript 中正确调用 swift 代码?的主要内容,如果未能解决你的问题,请参考以下文章