From 392404599a48153b8f4bff7ed39a8ad52b43c96a Mon Sep 17 00:00:00 2001 From: Dimitri Bouniol Date: Sun, 2 Mar 2025 01:16:54 -0800 Subject: [PATCH] Updated examples to use declarative push notifications Fixes #71 --- README.md | 22 ++++++++++++++----- .../WebPush/Push Message/Notification.swift | 6 +++++ .../WebPush/Push Message/PushMessage.swift | 2 ++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a7b61fa..caf1942 100644 --- a/README.md +++ b/README.md @@ -204,19 +204,22 @@ You'll also want to serve a `serviceWorker.mjs` file at the root of your server self.addEventListener('push', function(event) { const data = event.data?.json() ?? {}; event.waitUntil((async () => { + const notification = data?.notification ?? {} /// Try parsing the data, otherwise use fallback content. DO NOT skip sending the notification, as you must display one for every push message that is received or your subscription will be dropped. - let title = data?.title ?? "Your App Name"; - const body = data?.body ?? "New Content Available!"; + const title = notification.title ?? "Your App Name"; + const body = notification.body ?? "New Content Available!"; await self.registration.showNotification(title, { - body, - icon: "/notification-icon.png", /// Only some browsers support this. - data + body, + requireInteraction: notification.require_interaction ?? false, + ...notification, }); })()); }); ``` +In the example above, we are using the new **Declarative Push Notification** format for our message payload so the browser can automatically skip requiring the service worker, but you can send send any data payload and interpret it in your service worker should you choose. Note that doing so will require more resources on your user's devices when Declarative Push Notifications are otherwise supported. + > [!NOTE] > `.mjs` here allows your code to import other js modules as needed. If you are not using Vapor, please make sure your server uses the correct mime type for this file extension. @@ -349,7 +352,12 @@ import WebPush do { try await manager.send( - json: ["title": "Test Notification", "body": "Hello, World!"], + /// We use a declarative push notification to allow newer browsers to deliver the notification to users on our behalf. + notification: PushMessage.Notification( + destination: URL(string: "https://example.com/notificationDetails")!, + title: "Test Notification", + body: "Hello, World!" + ), to: subscriber /// If sent from a request, pass the request's logger here to maintain its metadata. // logger: request.logger @@ -367,6 +375,8 @@ do { Your service worker will receive this message, decode it, and present it to the user. +You can also send JSON (`send(json: ...)`), data (`send(data: ...)`), or text (`send(string: ...)`) and have your service worker interpret the payload as it sees fit. + > [!NOTE] > Although the spec supports it, most browsers do not support silent notifications, and will drop a subscription if they are used. diff --git a/Sources/WebPush/Push Message/Notification.swift b/Sources/WebPush/Push Message/Notification.swift index 2ac6964..753c1f2 100644 --- a/Sources/WebPush/Push Message/Notification.swift +++ b/Sources/WebPush/Push Message/Notification.swift @@ -122,6 +122,9 @@ extension PushMessage { /// Initialize a new Declarative Push Notification. + /// + /// - Important: The entire notification must fit within ``WebPushManager/maximumMessageSize`` once encoded, or sending the notification will fail. Keep this in mind when specifying data to be sent along with the notification. + /// /// - Parameters: /// - kind: The kind of notification to send. Defaults to ``PushMessage/NotificationKind/declarative``. /// - destination: The destination URL that should be opened when the user interacts with the notification. @@ -164,6 +167,9 @@ extension PushMessage { extension PushMessage.Notification where Contents == Never { /// Initialize a new Declarative Push Notification. + /// + /// - Important: The entire notification must fit within ``WebPushManager/maximumMessageSize`` once encoded, or sending the notification will fail. Keep this in mind when specifying data to be sent along with the notification. + /// /// - Parameters: /// - kind: The kind of notification to send. Defaults to ``PushMessage/NotificationKind/declarative``. /// - destination: The destination URL that should be opened when the user interacts with the notification. diff --git a/Sources/WebPush/Push Message/PushMessage.swift b/Sources/WebPush/Push Message/PushMessage.swift index ecfbb98..17c52c7 100644 --- a/Sources/WebPush/Push Message/PushMessage.swift +++ b/Sources/WebPush/Push Message/PushMessage.swift @@ -7,4 +7,6 @@ // /// Common Push Message types. +/// +/// Currently, only ``PushMessage/Notification`` is defined. public enum PushMessage: Sendable {}