@@ -8,12 +8,10 @@ import UserNotifications
8
8
import Shared
9
9
10
10
protocol NotificationManagerProtocol {
11
- func requestAuthorization( completion: @escaping ( Bool , Error ? ) -> Void )
12
- func requestAuthorization( completion: @escaping ( Result < Bool , Error > ) -> Void )
11
+ func requestAuthorization( completion: @escaping @ Sendable ( Bool , Error ? ) -> Void )
12
+ func requestAuthorization( completion: @escaping @ Sendable ( Result < Bool , Error > ) -> Void )
13
13
func requestAuthorization( ) async throws -> Bool
14
- func getNotificationSettings( sendTelemetry: Bool , completion: @escaping ( UNNotificationSettings ) -> Void )
15
14
func getNotificationSettings( sendTelemetry: Bool ) async -> UNNotificationSettings
16
- func hasPermission( completion: @escaping ( Bool ) -> Void )
17
15
func hasPermission( ) async -> Bool
18
16
func schedule( title: String ,
19
17
body: String ,
@@ -29,37 +27,33 @@ protocol NotificationManagerProtocol {
29
27
categoryIdentifier: String ,
30
28
interval: TimeInterval ,
31
29
repeats: Bool )
32
- func findDeliveredNotifications( completion : @escaping ( [ UNNotification ] ) -> Void )
33
- func findDeliveredNotificationForId( id: String , completion : @escaping ( UNNotification ? ) -> Void )
30
+ func findDeliveredNotifications( ) async -> [ UNNotification ]
31
+ func findDeliveredNotificationForId( id: String ) async -> UNNotification ?
34
32
func removeAllPendingNotifications( )
35
33
func removePendingNotificationsWithId( ids: [ String ] )
36
34
}
37
35
38
36
class NotificationManager : NotificationManagerProtocol {
37
+ private let telemetry : NotificationManagerTelemetry
39
38
private var center : UserNotificationCenterProtocol
40
39
41
- init ( center: UserNotificationCenterProtocol = UNUserNotificationCenter . current ( ) ) {
40
+ init ( center: UserNotificationCenterProtocol = UNUserNotificationCenter . current ( ) ,
41
+ telemetry: NotificationManagerTelemetry = NotificationManagerTelemetry ( ) ) {
42
42
self . center = center
43
+ self . telemetry = telemetry
43
44
}
44
45
45
46
// Requests the user’s authorization to allow local and remote notifications and sends Telemetry
46
- func requestAuthorization( completion: @escaping ( Bool , Error ? ) -> Void ) {
47
+ func requestAuthorization( completion: @escaping @ Sendable ( Bool , Error ? ) -> Void ) {
47
48
center. requestAuthorization ( options: [ . alert, . badge, . sound] ) { ( granted, error) in
48
49
completion ( granted, error)
49
50
50
- guard !AppConstants. isRunningUnitTest else { return }
51
-
52
- let extras = [ TelemetryWrapper . EventExtraKey. notificationPermissionIsGranted. rawValue:
53
- granted]
54
- TelemetryWrapper . recordEvent ( category: . prompt,
55
- method: . tap,
56
- object: . notificationPermission,
57
- extras: extras)
51
+ self . telemetry. sendNotificationPermissionPrompt ( isPermissionGranted: granted)
58
52
}
59
53
}
60
54
61
55
@available ( * , renamed: " requestAuthorization() " )
62
- func requestAuthorization( completion: @escaping ( Result < Bool , Error > ) -> Void ) {
56
+ func requestAuthorization( completion: @escaping @ Sendable ( Result < Bool , Error > ) -> Void ) {
63
57
self . requestAuthorization { granted, error in
64
58
if let error = error {
65
59
completion ( . failure( error) )
@@ -78,56 +72,29 @@ class NotificationManager: NotificationManagerProtocol {
78
72
}
79
73
80
74
// Retrieves the authorization and feature-related notification settings and sends Telemetry
81
- func getNotificationSettings( sendTelemetry: Bool = false ,
82
- completion: @escaping ( UNNotificationSettings ) -> Void ) {
83
- center. getNotificationSettings { settings in
84
- completion ( settings)
85
-
86
- guard sendTelemetry else { return }
87
- self . sendTelemetry ( settings: settings)
88
- }
89
- }
90
-
91
75
func getNotificationSettings( sendTelemetry: Bool = false ) async -> UNNotificationSettings {
92
- return await withCheckedContinuation { continuation in
93
- getNotificationSettings ( sendTelemetry: sendTelemetry) { result in
94
- continuation. resume ( returning: result)
95
- }
96
- }
97
- }
76
+ let settings = await center. notificationSettings ( )
98
77
99
- // Determines if the user has allowed notifications
100
- func hasPermission( completion: @escaping ( Bool ) -> Void ) {
101
- getNotificationSettings { settings in
102
- var hasPermission = false
103
- switch settings. authorizationStatus {
104
- case . authorized, . ephemeral, . provisional:
105
- hasPermission = true
106
- case . notDetermined, . denied:
107
- fallthrough
108
- @unknown default :
109
- hasPermission = false
110
- }
111
- completion ( hasPermission)
78
+ if sendTelemetry {
79
+ telemetry. sendNotificationPermission ( settings: settings)
112
80
}
81
+
82
+ return settings
113
83
}
114
84
115
85
// Determines if the user has allowed notifications
116
86
func hasPermission( ) async -> Bool {
117
- // FXIOS-11895 Temporary test for reverting continuation workaround we put in place for iOS 18.0 (beta?) users
118
- if ContinuationsChecker . shouldUseCheckedContinuation {
119
- await withCheckedContinuation { continuation in
120
- hasPermission { hasPermission in
121
- continuation. resume ( returning: hasPermission)
122
- }
123
- }
124
- } else {
125
- await withUnsafeContinuation { continuation in
126
- hasPermission { hasPermission in
127
- continuation. resume ( returning: hasPermission)
128
- }
129
- }
87
+ let settings = await getNotificationSettings ( )
88
+ var hasPermission = false
89
+ switch settings. authorizationStatus {
90
+ case . authorized, . ephemeral, . provisional:
91
+ hasPermission = true
92
+ case . notDetermined, . denied:
93
+ fallthrough
94
+ @unknown default :
95
+ hasPermission = false
130
96
}
97
+ return hasPermission
131
98
}
132
99
133
100
// Scheduling push notification based on the Date trigger (Ex 25 December at 10:00PM)
@@ -169,21 +136,17 @@ class NotificationManager: NotificationManagerProtocol {
169
136
}
170
137
171
138
// Fetches all delivered notifications that are still present in Notification Center.
172
- func findDeliveredNotifications( completion: @escaping ( [ UNNotification ] ) -> Void ) {
173
- center. getDeliveredNotifications { notificationList in
174
- completion ( notificationList)
175
- }
139
+ func findDeliveredNotifications( ) async -> [ UNNotification ] {
140
+ return await center. deliveredNotifications ( )
176
141
}
177
142
178
143
// Fetches all delivered notifications that are still present in Notification Center by id
179
- func findDeliveredNotificationForId( id: String ,
180
- completion: @escaping ( UNNotification ? ) -> Void ) {
181
- findDeliveredNotifications { notificationList in
182
- let notification = notificationList. first ( where: { notification -> Bool in
183
- notification. request. identifier == id
184
- } )
185
- completion ( notification)
186
- }
144
+ func findDeliveredNotificationForId( id: String ) async -> UNNotification ? {
145
+ let notificationList : [ UNNotification ] = await findDeliveredNotifications ( )
146
+ let notification = notificationList. first ( where: { notification -> Bool in
147
+ notification. request. identifier == id
148
+ } )
149
+ return notification
187
150
}
188
151
189
152
// Remove all pending notifications
@@ -221,34 +184,4 @@ class NotificationManager: NotificationManagerProtocol {
221
184
trigger: trigger)
222
185
center. add ( request, withCompletionHandler: nil )
223
186
}
224
-
225
- private func sendTelemetry( settings: UNNotificationSettings ) {
226
- guard !AppConstants. isRunningUnitTest else { return }
227
-
228
- var authorizationStatus = " "
229
- switch settings. authorizationStatus {
230
- case . authorized: authorizationStatus = " authorized "
231
- case . denied: authorizationStatus = " denied "
232
- case . ephemeral: authorizationStatus = " ephemeral "
233
- case . provisional: authorizationStatus = " provisional "
234
- case . notDetermined: authorizationStatus = " notDetermined "
235
- @unknown default : authorizationStatus = " notDetermined "
236
- }
237
-
238
- var alertSetting = " "
239
- switch settings. alertSetting {
240
- case . enabled: alertSetting = " enabled "
241
- case . disabled: alertSetting = " disabled "
242
- case . notSupported: alertSetting = " notSupported "
243
- @unknown default : alertSetting = " notSupported "
244
- }
245
-
246
- let extras = [ TelemetryWrapper . EventExtraKey. notificationPermissionStatus. rawValue: authorizationStatus,
247
- TelemetryWrapper . EventExtraKey. notificationPermissionAlertSetting. rawValue: alertSetting]
248
-
249
- TelemetryWrapper . recordEvent ( category: . action,
250
- method: . view,
251
- object: . notificationPermission,
252
- extras: extras)
253
- }
254
187
}
0 commit comments