@@ -17,8 +17,11 @@ import Foundation
17
17
import Logging
18
18
import NIOCore
19
19
import NIOFoundationCompat
20
+ import NIOSSL
20
21
21
22
public final class APNSClient {
23
+ internal static let loggingDisabled = Logger (
24
+ label: " APNS-do-not-log " , factory: { _ in SwiftLogNoOpLogHandler ( ) } )
22
25
23
26
private let configuration : APNSConfiguration
24
27
private let bearerTokenFactory : APNSBearerTokenFactory
@@ -27,10 +30,6 @@ public final class APNSClient {
27
30
internal let jsonEncoder = JSONEncoder ( )
28
31
internal let jsonDecoder = JSONDecoder ( )
29
32
30
- private var logger : Logger ? {
31
- configuration. logger
32
- }
33
-
34
33
/// APNSClient manages the connection and sending of push notifications to Apple's servers
35
34
///
36
35
/// - Parameter configuration: `APNSConfiguration` contains various values the client will need.
@@ -42,9 +41,18 @@ public final class APNSClient {
42
41
authenticationConfig: configuration. authenticationConfig,
43
42
logger: configuration. logger
44
43
)
44
+
45
+ let httpClientConfiguration = HTTPClient . Configuration (
46
+ proxy: configuration. proxy? . base
47
+ )
48
+
45
49
self . httpClient = HTTPClient (
46
- eventLoopGroupProvider: configuration. eventLoopGroupProvider. httpClientValue
50
+ eventLoopGroupProvider: configuration. eventLoopGroupProvider. httpClientValue,
51
+ configuration: httpClientConfiguration,
52
+ backgroundActivityLogger: configuration. logger ?? APNSClient . loggingDisabled
47
53
)
54
+
55
+ jsonEncoder. outputFormatting = . withoutEscapingSlashes
48
56
}
49
57
50
58
/// Shuts down the connections
@@ -74,10 +82,12 @@ public final class APNSClient {
74
82
priority: Int ? ,
75
83
collapseIdentifier: String ? ,
76
84
topic: String ? ,
77
- apnsID: UUID ?
85
+ apnsID: UUID ? ,
86
+ logger: Logger ? = nil
78
87
) async throws {
79
-
80
88
let topic = topic ?? configuration. topic
89
+ let logger = logger ?? configuration. logger
90
+
81
91
let urlBase : String =
82
92
environment? . url. absoluteString ?? configuration. environment. url. absoluteString
83
93
@@ -87,7 +97,7 @@ public final class APNSClient {
87
97
request. headers. add ( name: " user-agent " , value: " APNS/swift-nio " )
88
98
request. headers. add ( name: " content-length " , value: " \( payload. readableBytes) " )
89
99
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)
91
101
request. headers. add ( name: " host " , value: urlBase)
92
102
93
103
if let priority = priority {
@@ -118,7 +128,9 @@ public final class APNSClient {
118
128
request,
119
129
timeout: configuration. timeout ?? . seconds( 30 )
120
130
)
131
+
121
132
logger? . debug ( " APNS request - finished - \( response. status) " )
133
+
122
134
if response. status != . ok {
123
135
let body = try await response. body. collect ( upTo: 1024 * 1024 )
124
136
@@ -130,13 +142,28 @@ public final class APNSClient {
130
142
}
131
143
132
144
extension 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)
140
167
}
141
168
}
142
169
@@ -172,7 +199,8 @@ extension APNSClient {
172
199
priority: Int ? = nil ,
173
200
collapseIdentifier: String ? = nil ,
174
201
topic: String ? = nil ,
175
- apnsID: UUID ? = nil
202
+ apnsID: UUID ? = nil ,
203
+ logger: Logger ? = nil
176
204
) async throws {
177
205
try await self . send (
178
206
APNSPayload ( alert: alert) ,
@@ -184,7 +212,8 @@ extension APNSClient {
184
212
priority: priority,
185
213
collapseIdentifier: collapseIdentifier,
186
214
topic: topic,
187
- apnsID: apnsID
215
+ apnsID: apnsID,
216
+ logger: logger
188
217
)
189
218
}
190
219
@@ -218,7 +247,8 @@ extension APNSClient {
218
247
priority: Int ? = nil ,
219
248
collapseIdentifier: String ? = nil ,
220
249
topic: String ? = nil ,
221
- apnsID: UUID ? = nil
250
+ apnsID: UUID ? = nil ,
251
+ logger: Logger ? = nil
222
252
) async throws {
223
253
struct BasicNotification : APNSNotification {
224
254
let aps : APNSPayload
@@ -233,7 +263,8 @@ extension APNSClient {
233
263
priority: priority,
234
264
collapseIdentifier: collapseIdentifier,
235
265
topic: topic,
236
- apnsID: apnsID
266
+ apnsID: apnsID,
267
+ logger: logger
237
268
)
238
269
}
239
270
@@ -267,14 +298,22 @@ extension APNSClient {
267
298
priority: Int ? = nil ,
268
299
collapseIdentifier: String ? = nil ,
269
300
topic: String ? = nil ,
270
- apnsID: UUID ? = nil
301
+ apnsID: UUID ? = nil ,
302
+ logger: Logger ? = nil
271
303
) async throws where Notification: APNSNotification {
272
304
let data : Data
273
305
if let encoder = encoder {
274
306
data = try encoder. encode ( notification)
275
307
} else {
276
308
data = try jsonEncoder. encode ( notification)
277
309
}
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
+
278
317
try await self . send (
279
318
raw: data,
280
319
pushType: pushType,
@@ -284,7 +323,8 @@ extension APNSClient {
284
323
priority: priority,
285
324
collapseIdentifier: collapseIdentifier,
286
325
topic: topic,
287
- apnsID: apnsID
326
+ apnsID: apnsID,
327
+ logger: loggerToUse
288
328
)
289
329
}
290
330
@@ -299,7 +339,8 @@ extension APNSClient {
299
339
priority: Int ? ,
300
340
collapseIdentifier: String ? ,
301
341
topic: String ? ,
302
- apnsID: UUID ? = nil
342
+ apnsID: UUID ? = nil ,
343
+ logger: Logger ? = nil
303
344
) async throws
304
345
where Bytes: Collection , Bytes. Element == UInt8 {
305
346
var buffer = ByteBufferAllocator ( ) . buffer ( capacity: payload. count)
@@ -313,7 +354,8 @@ extension APNSClient {
313
354
priority: priority,
314
355
collapseIdentifier: collapseIdentifier,
315
356
topic: topic,
316
- apnsID: apnsID
357
+ apnsID: apnsID,
358
+ logger: logger
317
359
)
318
360
}
319
361
}
0 commit comments