如何在WKWebView中捕获通知

问题描述 投票:4回答:1

我正在Swift 4中开发macOS桌面应用程序。它具有WKWebView,可加载发送通知的网页。默认情况下,不显示任何通知,也没有权限请求。

我需要一种显示通知并拦截它们的方法,以便我可以显示一个计数器。

任何想法如何实现这一目标?

swift macos webkit web-notifications
1个回答
2
投票

我正面临着同样的挑战,并通过注入脚本(WKUserScript)解决了这个问题,该脚本使用自定义实现覆盖了Web通知API,该实现利用WKUserScript将消息发送到将最终通知发布到的本机应用代码结束。

设置WKUserContentController

据我所知,要使用自定义WKUserContentController,必须以编程方式创建WKWebView。创建一个新的macOS应用程序项目我在WKWebView函数中扩展我的WKWebViewConfiguration,如下所示:

viewDidLoad

[首先,我从应用程序包中加载用户脚本,并将其添加到用户内容控制器中。我还添加了一个称为ViewController的消息处理程序,该消息处理程序可用于从JavaScript上下文回拨至本机代码。最后,我从应用程序包中加载了一个HTML文档示例,并使用窗口中的整个区域显示了Web视图。

覆盖通知API

这是注入的用户脚本,并且是Web override func viewDidLoad() { super.viewDidLoad() let userScriptURL = Bundle.main.url(forResource: "UserScript", withExtension: "js")! let userScriptCode = try! String(contentsOf: userScriptURL) let userScript = WKUserScript(source: userScriptCode, injectionTime: .atDocumentStart, forMainFrameOnly: false) let configuration = WKWebViewConfiguration() configuration.userContentController.addUserScript(userScript) configuration.userContentController.add(self, name: "notify") let documentURL = Bundle.main.url(forResource: "Document", withExtension: "html")! let webView = WKWebView(frame: view.frame, configuration: configuration) webView.loadFileURL(documentURL, allowingReadAccessTo: documentURL) view.addSubview(webView) } 的部分替代。在此一般问题的范围内,处理notify和发布通知就足够了。

Notification API

每次在JavaScript上下文中创建新通知时,都会调用用户内容控制器消息处理程序。

处理脚本消息

the typical notification permission request process(或其他应处理脚本消息的东西)需要符合/** * Incomplete Notification API override to enable native notifications. */ class NotificationOverride { // Grant permission by default to keep this example simple. // Safari 13 does not support class fields yet, so a static getter must be used. static get permission() { return "granted"; } // Safari 13 still uses callbacks instead of promises. static requestPermission (callback) { callback("granted"); } // Forward the notification text to the native app through the script message handler. constructor (messageText) { window.webkit.messageHandlers.notify.postMessage(messageText); } } // Override the global browser notification object. window.Notification = NotificationOverride; 并实现以下功能来处理调用:

ViewController

整个实现是关于在macOS中创建本地本地通知。但是,如果没有额外的努力,它将无法正常工作。

应用程序代理调整

在允许macOS应用发布通知之前,它必须先请求权限,例如网站。

WKScriptMessageHandler

如果在应用程序处于前台时应显示通知,则必须进一步扩展应用程序委托以符合WKScriptMessageHandler并实现:

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        let content = UNMutableNotificationContent()
        content.title = "WKWebView Notification Example"
        content.body = message.body as! String

        let uuidString = UUID().uuidString
        let request = UNNotificationRequest(identifier: uuidString, content: content, trigger: nil)

        let notificationCenter = UNUserNotificationCenter.current()
        notificationCenter.add(request) { (error) in
            if error != nil {
                NSLog(error.debugDescription)
            }
        }
    }

这需要func applicationDidFinishLaunching(_ aNotification: Notification) { UNUserNotificationCenter.current().requestAuthorization(options: [.alert]) { (granted, error) in // Enable or disable features based on authorization. } } 中的委托分配:

UNUserNotificationCenterDelegate

UNUserNotificationCenterDelegate可能根据您的要求而有所不同。

参考

我创建了func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler(UNNotificationPresentationOptions.alert) } ,可以渲染整个图片。

© www.soinside.com 2019 - 2024. All rights reserved.