77//
88
99import UIKit
10+ import UserNotifications
1011
1112
1213struct NotificationManager {
@@ -27,74 +28,72 @@ struct NotificationManager {
2728 case BolusStartDate
2829 }
2930
30- static var userNotificationSettings : UIUserNotificationSettings {
31- let retryBolusAction = UIMutableUserNotificationAction ( )
32- retryBolusAction. title = NSLocalizedString ( " Retry " , comment: " The title of the notification action to retry a bolus command " )
33- retryBolusAction. identifier = Action . RetryBolus. rawValue
34- retryBolusAction. activationMode = . background
35-
36- let bolusFailureCategory = UIMutableUserNotificationCategory ( )
37- bolusFailureCategory. identifier = Category . BolusFailure. rawValue
38- bolusFailureCategory. setActions ( [
39- retryBolusAction
40- ] ,
41- for: . default
42- )
31+ private static var notificationCategories : Set < UNNotificationCategory > {
32+ var categories = [ UNNotificationCategory] ( )
4333
44- return UIUserNotificationSettings (
45- types: [ . badge, . sound, . alert] ,
46- categories: [
47- bolusFailureCategory
48- ]
34+ let retryBolusAction = UNNotificationAction (
35+ identifier: Action . RetryBolus. rawValue,
36+ title: NSLocalizedString ( " Retry " , comment: " The title of the notification action to retry a bolus command " ) ,
37+ options: [ ]
4938 )
39+
40+ categories. append ( UNNotificationCategory (
41+ identifier: Category . BolusFailure. rawValue,
42+ actions: [ retryBolusAction] ,
43+ intentIdentifiers: [ ] ,
44+ options: [ ]
45+ ) )
46+
47+ return Set ( categories)
5048 }
5149
52- static func authorize( ) {
53- UIApplication . shared. registerUserNotificationSettings ( userNotificationSettings)
50+ static func authorize( delegate: UNUserNotificationCenterDelegate ) {
51+ let center = UNUserNotificationCenter . current ( )
52+
53+ center. delegate = delegate
54+ center. requestAuthorization ( options: [ . badge, . sound, . alert] , completionHandler: { _, _ in } )
55+ center. setNotificationCategories ( notificationCategories)
5456 }
5557
5658 // MARK: - Notifications
5759
5860 static func sendBolusFailureNotificationForAmount( _ units: Double , atStartDate startDate: Date ) {
59- let notification = UILocalNotification ( )
61+ let notification = UNMutableNotificationContent ( )
6062
61- notification. alertTitle = NSLocalizedString ( " Bolus " , comment: " The notification title for a bolus failure " )
62- notification. alertBody = String ( format: NSLocalizedString ( " %@ U bolus may have failed. " , comment: " The notification alert describing a possible bolus failure. The substitution parameter is the size of the bolus in units. " ) , NumberFormatter . localizedString ( from: NSNumber ( value: units) , number: . decimal) )
63- notification. soundName = UILocalNotificationDefaultSoundName
63+ notification. title = NSLocalizedString ( " Bolus " , comment: " The notification title for a bolus failure " )
64+ notification. body = String ( format: NSLocalizedString ( " %@ U bolus may have failed. " , comment: " The notification alert describing a possible bolus failure. The substitution parameter is the size of the bolus in units. " ) , NumberFormatter . localizedString ( from: NSNumber ( value: units) , number: . decimal) )
65+ notification. sound = UNNotificationSound . default ( )
6466
6567 if startDate. timeIntervalSinceNow >= TimeInterval ( minutes: - 5 ) {
66- notification. category = Category . BolusFailure. rawValue
68+ notification. categoryIdentifier = Category . BolusFailure. rawValue
6769 }
6870
6971 notification. userInfo = [
7072 UserInfoKey . BolusAmount. rawValue: units,
7173 UserInfoKey . BolusStartDate. rawValue: startDate
7274 ]
7375
74- UIApplication . shared. presentLocalNotificationNow ( notification)
76+ let request = UNNotificationRequest (
77+ // Only support 1 bolus notification at once
78+ identifier: Category . BolusFailure. rawValue,
79+ content: notification,
80+ trigger: nil
81+ )
82+
83+ UNUserNotificationCenter . current ( ) . add ( request)
7584 }
7685
7786 // Cancel any previous scheduled notifications in the Loop Not Running category
78- static func clearLoopNotRunningNotifications( ) {
79- let app = UIApplication . shared
80-
81- app. scheduledLocalNotifications? . filter ( {
82- $0. category == Category . LoopNotRunning. rawValue
83- } ) . forEach ( {
84- app. cancelLocalNotification ( $0)
85- } )
87+ static func clearPendingNotificationRequests( ) {
88+ UNUserNotificationCenter . current ( ) . removeAllPendingNotificationRequests ( )
8689 }
8790
8891 static func scheduleLoopNotRunningNotifications( ) {
89- let app = UIApplication . shared
90-
91- clearLoopNotRunningNotifications ( )
92-
9392 // Give a little extra time for a loop-in-progress to complete
9493 let gracePeriod = TimeInterval ( minutes: 0.5 )
9594
9695 for minutes : Double in [ 20 , 40 , 60 , 120 ] {
97- let notification = UILocalNotification ( )
96+ let notification = UNMutableNotificationContent ( )
9897 let failureInterval = TimeInterval ( minutes: minutes)
9998
10099 let formatter = DateComponentsFormatter ( )
@@ -103,46 +102,66 @@ struct NotificationManager {
103102 formatter. unitsStyle = . full
104103
105104 if let failueIntervalString = formatter. string ( from: failureInterval) ? . localizedLowercase {
106- notification. alertBody = String ( format: NSLocalizedString ( " Loop has not completed successfully in %@ " , comment: " The notification alert describing a long-lasting loop failure. The substitution parameter is the time interval since the last loop " ) , failueIntervalString)
105+ notification. body = String ( format: NSLocalizedString ( " Loop has not completed successfully in %@ " , comment: " The notification alert describing a long-lasting loop failure. The substitution parameter is the time interval since the last loop " ) , failueIntervalString)
107106 }
108107
109- notification. alertTitle = NSLocalizedString ( " Loop Failure " , comment: " The notification title for a loop failure " )
110- notification. fireDate = Date ( timeIntervalSinceNow: failureInterval + gracePeriod)
111- notification. soundName = UILocalNotificationDefaultSoundName
112- notification. category = Category . LoopNotRunning. rawValue
113-
114- app. scheduleLocalNotification ( notification)
108+ notification. title = NSLocalizedString ( " Loop Failure " , comment: " The notification title for a loop failure " )
109+ notification. sound = UNNotificationSound . default ( )
110+ notification. categoryIdentifier = Category . LoopNotRunning. rawValue
111+ notification. threadIdentifier = Category . LoopNotRunning. rawValue
112+
113+ let request = UNNotificationRequest (
114+ identifier: " \( Category . LoopNotRunning. rawValue) \( failureInterval) " ,
115+ content: notification,
116+ trigger: UNTimeIntervalNotificationTrigger (
117+ timeInterval: failureInterval + gracePeriod,
118+ repeats: false
119+ )
120+ )
121+
122+ UNUserNotificationCenter . current ( ) . add ( request)
115123 }
116124 }
117125
118126 static func sendPumpBatteryLowNotification( ) {
119- let notification = UILocalNotification ( )
127+ let notification = UNMutableNotificationContent ( )
128+
129+ notification. title = NSLocalizedString ( " Pump Battery Low " , comment: " The notification title for a low pump battery " )
130+ notification. body = NSLocalizedString ( " Change the pump battery immediately " , comment: " The notification alert describing a low pump battery " )
131+ notification. sound = UNNotificationSound . default ( )
132+ notification. categoryIdentifier = Category . PumpBatteryLow. rawValue
120133
121- notification. alertTitle = NSLocalizedString ( " Pump Battery Low " , comment: " The notification title for a low pump battery " )
122- notification. alertBody = NSLocalizedString ( " Change the pump battery immediately " , comment: " The notification alert describing a low pump battery " )
123- notification. soundName = UILocalNotificationDefaultSoundName
124- notification. category = Category . PumpBatteryLow. rawValue
134+ let request = UNNotificationRequest (
135+ identifier: Category . PumpBatteryLow. rawValue,
136+ content: notification,
137+ trigger: nil
138+ )
125139
126- UIApplication . shared . presentLocalNotificationNow ( notification )
140+ UNUserNotificationCenter . current ( ) . add ( request )
127141 }
128142
129143 static func sendPumpReservoirEmptyNotification( ) {
130- let notification = UILocalNotification ( )
131-
132- notification. alertTitle = NSLocalizedString ( " Pump Reservoir Empty " , comment: " The notification title for an empty pump reservoir " )
133- notification. alertBody = NSLocalizedString ( " Change the pump reservoir now " , comment: " The notification alert describing an empty pump reservoir " )
134- notification. soundName = UILocalNotificationDefaultSoundName
135- notification. category = Category . PumpReservoirEmpty. rawValue
136-
137- // TODO: Add an action to Suspend the pump
144+ let notification = UNMutableNotificationContent ( )
145+
146+ notification. title = NSLocalizedString ( " Pump Reservoir Empty " , comment: " The notification title for an empty pump reservoir " )
147+ notification. body = NSLocalizedString ( " Change the pump reservoir now " , comment: " The notification alert describing an empty pump reservoir " )
148+ notification. sound = UNNotificationSound . default ( )
149+ notification. categoryIdentifier = Category . PumpReservoirEmpty. rawValue
150+
151+ let request = UNNotificationRequest (
152+ // Not a typo: this should replace any pump reservoir low notifications
153+ identifier: Category . PumpReservoirLow. rawValue,
154+ content: notification,
155+ trigger: nil
156+ )
138157
139- UIApplication . shared . presentLocalNotificationNow ( notification )
158+ UNUserNotificationCenter . current ( ) . add ( request )
140159 }
141160
142161 static func sendPumpReservoirLowNotificationForAmount( _ units: Double , andTimeRemaining remaining: TimeInterval ? ) {
143- let notification = UILocalNotification ( )
162+ let notification = UNMutableNotificationContent ( )
144163
145- notification. alertTitle = NSLocalizedString ( " Pump Reservoir Low " , comment: " The notification title for a low pump reservoir " )
164+ notification. title = NSLocalizedString ( " Pump Reservoir Low " , comment: " The notification title for a low pump reservoir " )
146165
147166 let unitsString = NumberFormatter . localizedString ( from: NSNumber ( value: units) , number: . decimal)
148167
@@ -154,14 +173,20 @@ struct NotificationManager {
154173 intervalFormatter. includesTimeRemainingPhrase = true
155174
156175 if let remaining = remaining, let timeString = intervalFormatter. string ( from: remaining) {
157- notification. alertBody = String ( format: NSLocalizedString ( " %1$@ U left: %2$@ " , comment: " Low reservoir alert with time remaining format string. (1: Number of units remaining)(2: approximate time remaining) " ) , unitsString, timeString)
176+ notification. body = String ( format: NSLocalizedString ( " %1$@ U left: %2$@ " , comment: " Low reservoir alert with time remaining format string. (1: Number of units remaining)(2: approximate time remaining) " ) , unitsString, timeString)
158177 } else {
159- notification. alertBody = String ( format: NSLocalizedString ( " %1$@ U left " , comment: " Low reservoir alert format string. (1: Number of units remaining) " ) , unitsString)
178+ notification. body = String ( format: NSLocalizedString ( " %1$@ U left " , comment: " Low reservoir alert format string. (1: Number of units remaining) " ) , unitsString)
160179 }
161180
162- notification. soundName = UILocalNotificationDefaultSoundName
163- notification. category = Category . PumpReservoirLow. rawValue
181+ notification. sound = UNNotificationSound . default ( )
182+ notification. categoryIdentifier = Category . PumpReservoirLow. rawValue
183+
184+ let request = UNNotificationRequest (
185+ identifier: Category . PumpReservoirLow. rawValue,
186+ content: notification,
187+ trigger: nil
188+ )
164189
165- UIApplication . shared . presentLocalNotificationNow ( notification )
190+ UNUserNotificationCenter . current ( ) . add ( request )
166191 }
167192}
0 commit comments