@@ -17,8 +17,11 @@ import Foundation
1717import Logging
1818import NIOCore
1919import NIOFoundationCompat
20+ import NIOSSL
2021
2122public final class APNSClient {
23+ internal static let loggingDisabled = Logger (
24+ label: " APNS-do-not-log " , factory: { _ in SwiftLogNoOpLogHandler ( ) } )
2225
2326 private let configuration : APNSConfiguration
2427 private let bearerTokenFactory : APNSBearerTokenFactory
@@ -27,10 +30,6 @@ public final class APNSClient {
2730 internal let jsonEncoder = JSONEncoder ( )
2831 internal let jsonDecoder = JSONDecoder ( )
2932
30- private var logger : Logger ? {
31- configuration. logger
32- }
33-
3433 /// APNSClient manages the connection and sending of push notifications to Apple's servers
3534 ///
3635 /// - Parameter configuration: `APNSConfiguration` contains various values the client will need.
@@ -42,9 +41,18 @@ public final class APNSClient {
4241 authenticationConfig: configuration. authenticationConfig,
4342 logger: configuration. logger
4443 )
44+
45+ let httpClientConfiguration = HTTPClient . Configuration (
46+ proxy: configuration. proxy? . base
47+ )
48+
4549 self . httpClient = HTTPClient (
46- eventLoopGroupProvider: configuration. eventLoopGroupProvider. httpClientValue
50+ eventLoopGroupProvider: configuration. eventLoopGroupProvider. httpClientValue,
51+ configuration: httpClientConfiguration,
52+ backgroundActivityLogger: configuration. logger ?? APNSClient . loggingDisabled
4753 )
54+
55+ jsonEncoder. outputFormatting = . withoutEscapingSlashes
4856 }
4957
5058 /// Shuts down the connections
@@ -74,10 +82,12 @@ public final class APNSClient {
7482 priority: Int ? ,
7583 collapseIdentifier: String ? ,
7684 topic: String ? ,
77- apnsID: UUID ?
85+ apnsID: UUID ? ,
86+ logger: Logger ? = nil
7887 ) async throws {
79-
8088 let topic = topic ?? configuration. topic
89+ let logger = logger ?? configuration. logger
90+
8191 let urlBase : String =
8292 environment? . url. absoluteString ?? configuration. environment. url. absoluteString
8393
@@ -87,7 +97,7 @@ public final class APNSClient {
8797 request. headers. add ( name: " user-agent " , value: " APNS/swift-nio " )
8898 request. headers. add ( name: " content-length " , value: " \( payload. readableBytes) " )
8999 request. headers. add ( name: " apns-topic " , value: topic)
90- request. headers. add ( name: " apns-push-type " , value: pushType. rawValue)
100+ request. headers. add ( name: " apns-push-type " , value: pushType. base . rawValue)
91101 request. headers. add ( name: " host " , value: urlBase)
92102
93103 if let priority = priority {
@@ -118,7 +128,9 @@ public final class APNSClient {
118128 request,
119129 timeout: configuration. timeout ?? . seconds( 30 )
120130 )
131+
121132 logger? . debug ( " APNS request - finished - \( response. status) " )
133+
122134 if response. status != . ok {
123135 let body = try await response. body. collect ( upTo: 1024 * 1024 )
124136
@@ -130,13 +142,28 @@ public final class APNSClient {
130142}
131143
132144extension APNSClient {
133- public enum PushType : String {
134- case alert
135- case background
136- case mdm
137- case voip
138- case fileprovider
139- case complication
145+ public struct PushType : Hashable , Sendable {
146+ internal enum Base : String {
147+ case alert
148+ case background
149+ case mdm
150+ case voip
151+ case fileprovider
152+ case complication
153+ }
154+
155+ internal var base : Base
156+
157+ init ( _ base: Base ) {
158+ self . base = base
159+ }
160+
161+ public static let alert = PushType ( . alert)
162+ public static let background = PushType ( . background)
163+ public static let mdm = PushType ( . mdm)
164+ public static let voip = PushType ( . voip)
165+ public static let fileprovider = PushType ( . fileprovider)
166+ public static let complication = PushType ( . complication)
140167 }
141168}
142169
@@ -172,7 +199,8 @@ extension APNSClient {
172199 priority: Int ? = nil ,
173200 collapseIdentifier: String ? = nil ,
174201 topic: String ? = nil ,
175- apnsID: UUID ? = nil
202+ apnsID: UUID ? = nil ,
203+ logger: Logger ? = nil
176204 ) async throws {
177205 try await self . send (
178206 APNSPayload ( alert: alert) ,
@@ -184,7 +212,8 @@ extension APNSClient {
184212 priority: priority,
185213 collapseIdentifier: collapseIdentifier,
186214 topic: topic,
187- apnsID: apnsID
215+ apnsID: apnsID,
216+ logger: logger
188217 )
189218 }
190219
@@ -218,7 +247,8 @@ extension APNSClient {
218247 priority: Int ? = nil ,
219248 collapseIdentifier: String ? = nil ,
220249 topic: String ? = nil ,
221- apnsID: UUID ? = nil
250+ apnsID: UUID ? = nil ,
251+ logger: Logger ? = nil
222252 ) async throws {
223253 struct BasicNotification : APNSNotification {
224254 let aps : APNSPayload
@@ -233,7 +263,8 @@ extension APNSClient {
233263 priority: priority,
234264 collapseIdentifier: collapseIdentifier,
235265 topic: topic,
236- apnsID: apnsID
266+ apnsID: apnsID,
267+ logger: logger
237268 )
238269 }
239270
@@ -267,14 +298,22 @@ extension APNSClient {
267298 priority: Int ? = nil ,
268299 collapseIdentifier: String ? = nil ,
269300 topic: String ? = nil ,
270- apnsID: UUID ? = nil
301+ apnsID: UUID ? = nil ,
302+ logger: Logger ? = nil
271303 ) async throws where Notification: APNSNotification {
272304 let data : Data
273305 if let encoder = encoder {
274306 data = try encoder. encode ( notification)
275307 } else {
276308 data = try jsonEncoder. encode ( notification)
277309 }
310+
311+ let loggerToUse = logger ?? configuration. logger
312+ if let loggerLevel = loggerToUse? . logLevel, loggerLevel >= . debug {
313+ let payloadString = String ( data: data, encoding: . utf8) ?? " "
314+ loggerToUse? . debug ( " APNS Payload: \( payloadString) " )
315+ }
316+
278317 try await self . send (
279318 raw: data,
280319 pushType: pushType,
@@ -284,7 +323,8 @@ extension APNSClient {
284323 priority: priority,
285324 collapseIdentifier: collapseIdentifier,
286325 topic: topic,
287- apnsID: apnsID
326+ apnsID: apnsID,
327+ logger: loggerToUse
288328 )
289329 }
290330
@@ -299,7 +339,8 @@ extension APNSClient {
299339 priority: Int ? ,
300340 collapseIdentifier: String ? ,
301341 topic: String ? ,
302- apnsID: UUID ? = nil
342+ apnsID: UUID ? = nil ,
343+ logger: Logger ? = nil
303344 ) async throws
304345 where Bytes: Collection , Bytes. Element == UInt8 {
305346 var buffer = ByteBufferAllocator ( ) . buffer ( capacity: payload. count)
@@ -313,7 +354,8 @@ extension APNSClient {
313354 priority: priority,
314355 collapseIdentifier: collapseIdentifier,
315356 topic: topic,
316- apnsID: apnsID
357+ apnsID: apnsID,
358+ logger: logger
317359 )
318360 }
319361}
0 commit comments