You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
/// Topics are used to de-duplicate and overwrite messages on push services before they are delivered to a subscriber.
13
+
///
14
+
/// The topic is never delivered to your service worker, though is seen in plain text by the Push Service, so this type encodes it first to prevent leaking any information about the messages you are sending or your subscribers.
15
+
///
16
+
/// - Important: Since topics are sent in the clear to push services, they must be securely hashed. You must use a stable random value for this, such as the subscriber's ``UserAgentKeyMaterial/authenticationSecret``. This is fine for most applications, though you may wish to use a different key if your application requires it.
/// Create a new topic from encodable data and a salt.
24
+
///
25
+
/// - Important: Since topics are sent in the clear to push services, they must be securely hashed. You must use a stable random value for this, such as the subscriber's ``UserAgentKeyMaterial/authenticationSecret``. This is fine for most applications, though you may wish to use a different key if your application requires it.
26
+
///
27
+
/// - Parameters:
28
+
/// - encodableTopic: The encodable data that represents a stable topic. This can be a string, identifier, or any other token that can be encoded.
29
+
/// - salt: The salt that should be used when encoding the topic.
/// Prefer to use ``init(encodableTopic:salt:)`` when possible.
64
+
///
65
+
/// - Warning: This may be rejected by a Push Service if it is not 32 Base64 URL-safe characters, and will not be encrypted. Expect to handle a ``PushServiceError`` with a ``PushServiceError/response`` status code of `400 Bad Request` when it does.
Copy file name to clipboardExpand all lines: Sources/WebPush/WebPushManager.swift
+20-1Lines changed: 20 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -250,12 +250,14 @@ public actor WebPushManager: Sendable {
250
250
/// - Parameters:
251
251
/// - message: The message to send as raw data.
252
252
/// - subscriber: The subscriber to send the push message to.
253
+
/// - deduplicationTopic: The topic to use when deduplicating messages stored on a Push Service.
253
254
/// - expiration: The expiration of the push message, after wich delivery will no longer be attempted.
254
255
/// - urgency: The urgency of the delivery of the push message.
255
256
/// - logger: The logger to use for status updates. If not provided, the background activity logger will be used instead. When running in a server environment, your contextual logger should be used instead giving you full control of logging and metadata.
256
257
publicfunc send(
257
258
data message:someDataProtocol,
258
259
to subscriber:someSubscriberProtocol,
260
+
deduplicationTopic topic:Topic?=nil,
259
261
expiration:Expiration=.recommendedMaximum,
260
262
urgency:Urgency=.high,
261
263
logger:Logger?=nil
@@ -269,12 +271,13 @@ public actor WebPushManager: Sendable {
@@ -285,19 +288,22 @@ public actor WebPushManager: Sendable {
285
288
/// - Parameters:
286
289
/// - message: The message to send as a string.
287
290
/// - subscriber: The subscriber to send the push message to.
291
+
/// - deduplicationTopic: The topic to use when deduplicating messages stored on a Push Service.
288
292
/// - expiration: The expiration of the push message, after wich delivery will no longer be attempted.
289
293
/// - urgency: The urgency of the delivery of the push message.
290
294
/// - logger: The logger to use for status updates. If not provided, the background activity logger will be used instead. When running in a server environment, your contextual logger should be used instead giving you full control of logging and metadata.
291
295
publicfunc send(
292
296
string message:someStringProtocol,
293
297
to subscriber:someSubscriberProtocol,
298
+
deduplicationTopic topic:Topic?=nil,
294
299
expiration:Expiration=.recommendedMaximum,
295
300
urgency:Urgency=.high,
296
301
logger:Logger?=nil
297
302
)asyncthrows{
298
303
tryawaitrouteMessage(
299
304
message:.string(String(message)),
300
305
to: subscriber,
306
+
deduplicationTopic: topic,
301
307
expiration: expiration,
302
308
urgency: urgency,
303
309
logger: logger ?? backgroundActivityLogger
@@ -311,19 +317,22 @@ public actor WebPushManager: Sendable {
311
317
/// - Parameters:
312
318
/// - message: The message to send as JSON.
313
319
/// - subscriber: The subscriber to send the push message to.
320
+
/// - deduplicationTopic: The topic to use when deduplicating messages stored on a Push Service.
314
321
/// - expiration: The expiration of the push message, after wich delivery will no longer be attempted.
315
322
/// - urgency: The urgency of the delivery of the push message.
316
323
/// - logger: The logger to use for status updates. If not provided, the background activity logger will be used instead. When running in a server environment, your contextual logger should be used instead giving you full control of logging and metadata.
317
324
publicfunc send(
318
325
json message:someEncodable&Sendable,
319
326
to subscriber:someSubscriberProtocol,
327
+
deduplicationTopic topic:Topic?=nil,
320
328
expiration:Expiration=.recommendedMaximum,
321
329
urgency:Urgency=.high,
322
330
logger:Logger?=nil
323
331
)asyncthrows{
324
332
tryawaitrouteMessage(
325
333
message:.json(message),
326
334
to: subscriber,
335
+
deduplicationTopic: topic,
327
336
expiration: expiration,
328
337
urgency: urgency,
329
338
logger: logger ?? backgroundActivityLogger
@@ -334,12 +343,14 @@ public actor WebPushManager: Sendable {
334
343
/// - Parameters:
335
344
/// - message: The message to send.
336
345
/// - subscriber: The subscriber to sign the message against.
346
+
/// - deduplicationTopic: The topic to use when deduplicating messages stored on a Push Service.
337
347
/// - expiration: The expiration of the message.
338
348
/// - urgency: The urgency of the message.
339
349
/// - logger: The logger to use for status updates.
340
350
func routeMessage(
341
351
message:_Message,
342
352
to subscriber:someSubscriberProtocol,
353
+
deduplicationTopic topic:Topic?,
343
354
expiration:Expiration,
344
355
urgency:Urgency,
345
356
logger:Logger
@@ -353,6 +364,7 @@ public actor WebPushManager: Sendable {
353
364
privateKeyProvider: privateKeyProvider,
354
365
data: message.data,
355
366
subscriber: subscriber,
367
+
deduplicationTopic: topic,
356
368
expiration: expiration,
357
369
urgency: urgency,
358
370
logger: logger
@@ -361,6 +373,7 @@ public actor WebPushManager: Sendable {
361
373
tryawaithandler(
362
374
message,
363
375
Subscriber(subscriber),
376
+
topic,
364
377
expiration,
365
378
urgency
366
379
)
@@ -373,6 +386,7 @@ public actor WebPushManager: Sendable {
373
386
/// - applicationServerECDHPrivateKey: The private key to use for the key exchange. If nil, one will be generated.
374
387
/// - message: The message to send as raw data.
375
388
/// - subscriber: The subscriber to sign the message against.
389
+
/// - deduplicationTopic: The topic to use when deduplicating messages stored on a Push Service.
376
390
/// - expiration: The expiration of the message.
377
391
/// - urgency: The urgency of the message.
378
392
/// - logger: The logger to use for status updates.
@@ -381,6 +395,7 @@ public actor WebPushManager: Sendable {
381
395
privateKeyProvider:Executor.KeyProvider,
382
396
data message:someDataProtocol,
383
397
subscriber:someSubscriberProtocol,
398
+
deduplicationTopic topic:Topic?,
384
399
expiration:Expiration,
385
400
urgency:Urgency,
386
401
logger:Logger
@@ -483,6 +498,9 @@ public actor WebPushManager: Sendable {
#expect(Topic(unsafeTopic:"A really long test (with unsafe characters to boot ふふふ!)").topic =="A really long test (with unsafe characters to boot ふふふ!)")
#expect("\(Topic(unsafeTopic:"A really long test (with unsafe characters to boot ふふふ!)"))"=="A really long test (with unsafe characters to boot ふふふ!)")
#expect(tryJSONDecoder().decode(Topic.self, from:Data("\"A really long test (with unsafe characters to boot ふふふ!)\"".utf8))==Topic(unsafeTopic:"A really long test (with unsafe characters to boot ふふふ!)"))
0 commit comments