我正在Swift 4中开发macOS桌面应用程序。除其他外,它还有一个WKWebView,它加载了发送通知的网页。默认情况下,这些都不显示(也没有权限请求)。
我需要一种显示通知并以某种方式拦截它们的方式,以便我可以显示计数器(例如,收到了多少个通知)。
任何想法如何实现这一目标?
我正面临着同样的挑战,并通过注入脚本(WKUserScript
)解决了这个问题,该脚本使用自定义实现覆盖了Web通知API,该实现利用WKUserScript
将消息发送到将最终通知发布到的本机应用代码结束。
WKUserContentController
[创建新的macOS应用程序项目,我在WKUserContentController
函数中扩展了WKWebView
,如下所示:
viewDidLoad
[首先,我从应用程序包中加载用户脚本,并将其添加到用户内容控制器中。我还添加了一个称为ViewController
的消息处理程序,该消息处理程序可用于从JavaScript上下文回拨至本机代码。最后,我从应用程序包中加载了一个HTML文档示例,并使用窗口中的整个区域显示了Web视图。
这是注入的用户脚本,是Web通知API的简约替代。它不完整,因为它不涵盖(例如)通知请求处理,但足以用于演示。
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)
}
但是对于本示例的范围就足够了。每次在JavaScript上下文中创建新通知时,都会调用用户内容控制器消息处理程序。
notify
或任何应处理脚本消息的东西都需要符合window.Notification = function (messageText) {
window.webkit.messageHandlers.notify.postMessage(messageText);
};
并实现以下功能来处理调用:
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
,可以渲染整个图片。