使用 Swift 在 iOS WKWebview 中捕获 Javascript 事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34574864/
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
Catch Javascript Event in iOS WKWebview with Swift
提问by fraxool
I am building an app with web programming languages and want to start the camera when the user clicks on an HTML button. Since I want my camera view to be a custom one, I need to design it with Swift. So when the user clicks on this HTML button, I want to "catch" this click in Swift so I can start my native camera view.
我正在使用网络编程语言构建一个应用程序,并希望在用户单击 HTML 按钮时启动相机。因为我希望我的相机视图是自定义的,所以我需要用 Swift 设计它。所以当用户点击这个 HTML 按钮时,我想在 Swift 中“捕捉”这个点击,这样我就可以启动我的原生相机视图。
I know it can be done with the WKWebview, but I don't really know how to do that.
我知道它可以用 WKWebview 来完成,但我真的不知道如何做到这一点。
For example, my Javascript (jQuery) code could look like that :
例如,我的 Javascript (jQuery) 代码可能如下所示:
// User clicks to start the native camera with Swift
$(".camera_button").click(function() {
// Function to call the camera view from JS to Swift
});
Can you help me to do that?
你能帮我做吗?
Thanks.
谢谢。
回答by fraxool
Based on the answer from @Alex Pelletier, which really helped me, here is the solution the my question.
根据@Alex Pelletier 的回答,这对我很有帮助,这是我的问题的解决方案。
In my "loadView()" function, here is what I have :
在我的“loadView()”函数中,这是我所拥有的:
let contentController = WKUserContentController();
contentController.addScriptMessageHandler(
self,
name: "callbackHandler"
)
let config = WKWebViewConfiguration()
config.userContentController = contentController
webView = WKWebView(frame: CGRectZero, configuration: config)
webView.navigationDelegate = self
view = webView
My function to handle the Javascript event which is sent to Swift :
我处理发送到 Swift 的 Javascript 事件的函数:
func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage)
{
if(message.name == "callbackHandler") {
print("Launch my Native Camera")
}
}
... And finally, my Javascript (jQuery) code when a click happens on my camera button (in HTML) :
...最后,我的 Javascript (jQuery) 代码在我的相机按钮(HTML)上发生点击时:
$(document).ready(function() {
function callNativeApp () {
try {
webkit.messageHandlers.callbackHandler.postMessage("camera");
} catch(err) {
console.log('The native context does not exist yet');
}
}
$(".menu-camera-icon").click(function() {
callNativeApp();
});
});
I hope it will help someone else :-) !
我希望它会帮助别人:-)!
回答by Alex Pelletier
First lets create a js file. In the js, when an element has been you clicked you can send a message back like so:
首先让我们创建一个js文件。在 js 中,当你点击一个元素时,你可以像这样发送一条消息:
varmessageToPost = {'ButtonId':'clickMeButton'};
window.webkit.messageHandlers.buttonClicked.postMessage(messageToPost);
After you have created the js file and the wkwebview you need to inject the script:
创建 js 文件和 wkwebview 后,您需要注入脚本:
// Setup WKUserContentController instance for injecting user script
var userController:WKUserContentController= WKUserContentController()
// Get script that's to be injected into the document
let js:String= GetScriptFromResources()
// Specify when and where and what user script needs to be injected into the web document
var userScript:WKUserScript = WKUserScript(source: js,
injectionTime: WKUserScriptInjectionTime.AtDocumentEnd
forMainFrameOnly: false)
// Add the user script to the WKUserContentController instance
userController.addUserScript(userScript)
// Configure the WKWebViewConfiguration instance with the WKUserContentController
webCfg.userContentController= userController;
//set the message handler
userController.addScriptMessageHandler(self, name: "buttonClicked")
Finally you have to add listener function:
最后,您必须添加侦听器功能:
func userContentController(userContentController: WKUserContentController,
didReceiveScriptMessage message: WKScriptMessage) {
if let messageBody:NSDictionary= message.body as? NSDictionary{
// Do stuff with messageBody
}
}