I'm working on a macOS desktop app in Swift 4.
It has a WKWebView which loads up a web page that sends notifications.
None of the notifications are shown by default and there's also no permission request.
I need a way to show the notifications and intercept them, so that I can show a counter.
Any idea how to achieve this?
I was facing the same challenge and solved it by injecting a script (
WKUserScript
) which overrides the web notification API with a custom implementation that leverages theWKUserContentController
to send messages to the native app code which posts the final notifications in the end.Setting up
WKWebView
Programmatic creation of a
WKWebView
is necessary to use a customWKWebViewConfiguration
as far as I know. Creating a new macOS app project I extend myviewDidLoad
in theViewController
function like this:First I load the user script from the app bundle and add it to the user content controller. I also add a message handler called
notify
which can be used to phone back from the JavaScript context to native code. At the end I load an example HTML document from the app bundle and present the web view using the whole area available in the window.Overriding the Notification API
This is the injected user script and a partial override of the web Notification API. It is sufficient to handle the typical notification permission request process and posting of notifications in scope of this generic question.
Every time a new notification is created in the JavaScript context, the user content controller message handler is invoked.
Handling the Script Message
The
ViewController
(or whatever else should handle the script messages) needs to conform toWKScriptMessageHandler
and implement the following function to handle invocations:The whole implementation is about the creation of a local, native notification in macOS. It does not work yet without additional effort, though.
App Delegate Adjustments
Before a macOS app is allowed to post notifications, it must request the permissions to do so, like a website.
If notifications should be presented while the app is in the foreground, the app delegate must be extended further to conform to
UNUserNotificationCenterDelegate
and implement:which requires the delegate assignment in
applicationDidFinishLaunching(_:)
:The
UNNotificationPresentationOptions
may vary according to your requirements.Reference
I created an example project available on GitHub which renders the whole picture.