当特定屏幕以 html 显示时,从 WKWebView 向 Swift 获取通知

Posted

技术标签:

【中文标题】当特定屏幕以 html 显示时,从 WKWebView 向 Swift 获取通知【英文标题】:Get notification from WKWebView to Swift when specific screen is shown in html 【发布时间】:2018-03-13 07:16:50 【问题描述】:

我有一个sample html

我使用WKWebView 来显示这个html。我想要的是,当用户完成游戏时,即出现“高分”屏幕时,我们也会在代码中收到通知(即快速),以便我们关闭该视图并获得最高分。

有什么可能的方法?

我做了以下,但它没有提供任何功能

func showHtml5()

    var wkWebView = WKWebView()
    let frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)

    let contentController = WKUserContentController()
    contentController.add(self, name: "onVisibilityChanged")

    let config = WKWebViewConfiguration()
    config.userContentController = contentController

    wkWebView = WKWebView(frame: frame, configuration: config)
    wkWebView.navigationDelegate = self as? WKNavigationDelegate


    if let url = URL(string: "https://previews.envatousercontent.com/files/240466341/index.html") 
        wkWebView.load(URLRequest(url: url))
    

    self.destination.view.addSubview(wkWebView)



func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) 
    print("message is :\(message)")

    if(message.name == " onVisibilityChanged") 
        print("FROM javascript")
    

【问题讨论】:

不错 game 虽然... 【参考方案1】:

您没有完全设置您的通信。快速设置看起来不错,但没有调用您的侦听器函数,因为您没有发送任何消息。为了从 Web 视图接收消息,您需要将消息发布到该特定消息处理程序。因此,如果您注册了一个名为 onVisibilityChanged 的消息处理程序,您需要从您的 javascript 向该处理程序发布一条消息。

在你的 javascript eventListener 内部这样做:

function onVisibilityChanged() 
    if (document.hidden || document.mozHidden || document.webkitHidden || document.msHidden) 
        cr_setSuspended(true);
     else 
        cr_setSuspended(false);
    

    var message = 
        "whatever": "you want to send"
    

    window.webkit.messageHandlers.onVisibilityChanged.postMessage(message);
;

然后像这样阅读您的消息:

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) 
    guard let body = message.body as? [String:Any] else 
        return
    

    print("message from the other side >> \(body["whatever"])")

【讨论】:

【参考方案2】:

你可以使用window.location = "<your protocol name>:<some payload>";

它会触发 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler 委托方法,您可以在其中使用取消处理检查您的协议名称以防止加载页面:

if ([navigationAction.request.URL.absoluteString.stringByRemovingPercentEncoding hasPrefix:@"<your protocol name>"]) 
    decisionHandler(WKNavigationActionPolicyCancel);

此示例适用于我项目中的 Objective-C。 Swift 的实现也有类似的行为。

【讨论】:

以上是关于当特定屏幕以 html 显示时,从 WKWebView 向 Swift 获取通知的主要内容,如果未能解决你的问题,请参考以下文章

通过ajax获取一个多位数,当容器显示在屏幕可视区时,让数字以滚动的形式显示

当用户在 UITextView 中选择特定单词时

当屏幕尺寸小于特定尺寸时隐藏 div 元素

在 ffmpeg 中从单个图像创建特定持续时间的视频

如何在 Swift 5 中以编程方式在特定屏幕(即主显示器而不是外部显示器)上显示窗口? [苹果系统; Xcode 15]

当单元格不可见时,UITableView indexPathForCell 返回 null