我正在使用 Swift 4 开发 macOS 桌面应用程序。
它有一个 WKWebView ,它加载一个发送通知的网页。
默认情况下不显示任何通知,也没有权限请求。
我需要一种显示通知并拦截它们的方法,以便我可以显示一个计数器。
知道如何实现这一目标吗?
我正在使用 Swift 4 开发 macOS 桌面应用程序。
它有一个 WKWebView ,它加载一个发送通知的网页。
默认情况下不显示任何通知,也没有权限请求。
我需要一种显示通知并拦截它们的方法,以便我可以显示一个计数器。
知道如何实现这一目标吗?
我面临着同样的挑战,并通过注入一个脚本WKUserScript(WKUserContentController
WKWebView据我所知,必须以编程方式创建 aWKWebView才能使用自定义。WKWebViewConfiguration创建一个新的 macOS 应用程序项目,我在函数中扩展我viewDidLoad的ViewController功能,如下所示:
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,可用于从 JavaScript 上下文回电到本机代码。最后,我从应用程序包中加载一个示例 HTML 文档,并使用窗口中可用的整个区域呈现 Web 视图。
这是注入的用户脚本和 web Notification API的部分覆盖。在这个通用问题的范围内处理典型的通知权限请求过程和发布通知就足够了。
/**
* 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;
每次在 JavaScript 上下文中创建新通知时,都会调用用户内容控制器消息处理程序。
(ViewController或任何其他应该处理脚本消息的)需要符合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)
}
}
}
整个实现是关于在 macOS 中创建本地、本机通知。但是,如果没有额外的努力,它还不能工作。
在允许 macOS 应用程序发布通知之前,它必须请求这样做的权限,例如网站。
func applicationDidFinishLaunching(_ aNotification: Notification) {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert]) { (granted, error) in
// Enable or disable features based on authorization.
}
}
如果应在应用程序处于前台时显示通知,则必须进一步扩展应用程序委托以符合UNUserNotificationCenterDelegate并实现:
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler(UNNotificationPresentationOptions.alert)
}
这需要委托分配applicationDidFinishLaunching(_:):
UNUserNotificationCenter.current().delegate = self
UNNotificationPresentationOptions可能会根据您的要求而有所不同。
我在 GitHub 上创建了一个示例项目,它呈现了整个画面。