【问题标题】:Catch Javascript Event in iOS WKWebview with Swift使用 Swift 在 iOS WKWebview 中捕获 Javascript 事件
【发布时间】:2016-04-07 02:30:14
【问题描述】:

我正在使用网络编程语言构建一个应用程序,并希望在用户单击 HTML 按钮时启动相机。因为我希望我的相机视图是自定义的,所以我需要用 Swift 来设计它。所以当用户点击这个 HTML 按钮时,我想在 Swift 中“捕捉”这个点击,这样我就可以开始我的原生相机视图了。

我知道可以使用 WKWebview 来完成,但我真的不知道该怎么做。

例如,我的 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
});

你能帮我做吗?

谢谢。

【问题讨论】:

    标签: javascript jquery ios swift swift2


    【解决方案1】:

    首先让我们创建一个 js 文件。在 js 中,当您单击某个元素时,您可以像这样发送消息:

    varmessageToPost = {'ButtonId':'clickMeButton'};
    window.webkit.messageHandlers.buttonClicked.postMessage(messageToPost);
    

    创建完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")  
    

    最后你必须添加监听函数:

    func userContentController(userContentController: WKUserContentController,
                               didReceiveScriptMessage message: WKScriptMessage) {
    
            if let messageBody:NSDictionary= message.body as? NSDictionary{
                // Do stuff with messageBody
            }
    
        }
    

    Source Code

    【讨论】:

    • 非常感谢。你的回答真的帮助了我。我将发布我的问题的完整解决方案。
    • @fraxool 如果它真的对你有帮助,请接受这个答案
    【解决方案2】:

    根据@Alex Pelletier 的回答,这对我很有帮助,这是我的问题的解决方案。

    在我的“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
    

    我处理发送到 Swift 的 Javascript 事件的函数:

    func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage)
        {
            if(message.name == "callbackHandler") {
                print("Launch my Native Camera")
            }
        }
    

    ... 最后,我的 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();
        });
    });
    

    我希望它会帮助别人:-)!

    【讨论】:

    • 太好了,非常感谢!您是否有提示/解决方案如何获取相机并将每个图像发送回 JS?
    • @HR123 在我看来,最好的方法是从本地 iOs 代码(Objective-C 或 Swift)处理相机视图,将其上传到某处(例如 Amazon S3),然后获取上传URL 并将此 URL 发送回 JS ;-) .
    • 这非常有帮助。谢谢@fraxool!
    【解决方案3】:

    首先,设置html字符串:

    var playerURL = """"
        https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/\(trackId)%3Fsecret_token%3D\(secretToken)&auto_play=false&hide_related=true&show_comments=false&show_user=false&show_reposts=false&show_teaser=false&visual=false
    """
    

    其次,创建您的WKWebView 并进行配置

    private var webView: WKWebView?
    
    override func awakeFromNib() {
        super.awakeFromNib()
        
        ...(1)...
        
        self.webView?.navigationDelegate = self
        self.webView?.isUserInteractionEnabled = true
        self.webView?.scrollView.isScrollEnabled = false
        self.webView?.allowsLinkPreview  = false
        self.webView?.contentMode = .scaleAspectFit
        self.webView?.loadHTMLString(self.playerUrl, baseURL: nil)
    
        DispatchQueue.main.async {
            self.webView = WKWebView(frame: self.viewSoundclound.bounds, configuration: config)
            guard let webView = self.webView else { return }
            self.viewSoundclound.addSubview(webView)
        }
    }
    

    第三,设置你要添加到WKWebViewJavasScript脚本的配置

     override func awakeFromNib() {
        super.awakeFromNib()
        let config = WKWebViewConfiguration()
        let script = WKUserScript(source: self.eventListenerScript, injectionTime: .atDocumentEnd, forMainFrameOnly: false)
        config.userContentController.addUserScript(script)
        config.userContentController.add(self, name: "soundCloundEvents")
    
        ...(2)...
    }
    

    之后,创建您的脚本。重要提示:'messageHandler.(name).postMessage' 中的名称必须与此行中的名称相同:

    'config.userContentController.add(self, name: "soundCloundEvents")'
    
    private var eventListenerScript = """
        var iframe = document.querySelector('iframe');
        widget = SC.Widget(iframe);
        widget.bind(SC.Widget.Events.PLAY, function() {
            window.webkit.messageHandlers.soundCloundEvents.postMessage('PLAY');
        });
        widget.bind(SC.Widget.Events.FINISH, function() {
            window.webkit.messageHandlers.soundCloundEvents.postMessage('FINISH');
        });
    """
    

    最后,扩展Controller或Cell(本例)来监听脚本

    extension PodcastsListTableViewCell: WKScriptMessageHandler {
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        print(message)
       }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-06
      • 2018-01-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多