@@ -11,6 +11,8 @@ import LoopKit
1111
1212public class AlertStore {
1313
14+ static let totalFetchLimit = 500
15+
1416 public enum AlertStoreError : Error {
1517 case notFound
1618 }
@@ -87,18 +89,18 @@ public class AlertStore {
8789
8890 public func recordAcknowledgement( of identifier: Alert . Identifier , at date: Date = Date ( ) ,
8991 completion: ( ( Result < Void , Error > ) -> Void ) ? = nil ) {
90- recordUpdateOfLatest ( of : identifier,
91- addingPredicate: NSPredicate ( format: " acknowledgedDate == nil " ) ,
92- with: {
93- $0. acknowledgedDate = date
94- return . save
95- } ,
96- completion: completion)
92+ recordUpdateOfAll ( identifier : identifier,
93+ addingPredicate: NSPredicate ( format: " acknowledgedDate == nil " ) ,
94+ with: {
95+ $0. acknowledgedDate = date
96+ return . save
97+ } ,
98+ completion: completion)
9799 }
98100
99101 public func recordRetraction( of identifier: Alert . Identifier , at date: Date = Date ( ) ,
100102 completion: ( ( Result < Void , Error > ) -> Void ) ? = nil ) {
101- recordUpdateOfLatest ( of : identifier,
103+ recordUpdateOfLatest ( identifier : identifier,
102104 addingPredicate: NSPredicate ( format: " retractedDate == nil " ) ,
103105 with: {
104106 // if the alert was retracted before it was ever shown, delete it.
@@ -135,29 +137,40 @@ public class AlertStore {
135137// MARK: Private functions
136138
137139extension AlertStore {
138-
139- private func recordUpdateOfLatest( of identifier: Alert . Identifier ,
140+
141+ private func recordUpdateOfAll( identifier: Alert . Identifier ,
142+ addingPredicate predicate: NSPredicate ,
143+ with updateBlock: @escaping ManagedObjectUpdateBlock ,
144+ completion: ( ( Result < Void , Error > ) -> Void ) ? ) {
145+ managedObjectContext. perform {
146+ self . lookupAll ( identifier: identifier, predicate: predicate) {
147+ switch $0 {
148+ case . success( let objects) :
149+ if objects. count > 0 {
150+ let result = self . update ( objects: objects, with: updateBlock)
151+ completion ? ( result)
152+ } else {
153+ self . log. error ( " Alert not found for update: %{public}@ " , identifier. value)
154+ completion ? ( . failure( AlertStoreError . notFound) )
155+ }
156+ case . failure( let error) :
157+ completion ? ( . failure( error) )
158+ }
159+ }
160+ }
161+ }
162+
163+ private func recordUpdateOfLatest( identifier: Alert . Identifier ,
140164 addingPredicate predicate: NSPredicate ,
141- with block : @escaping ManagedObjectUpdateBlock ,
165+ with updateBlock : @escaping ManagedObjectUpdateBlock ,
142166 completion: ( ( Result < Void , Error > ) -> Void ) ? ) {
143- self . managedObjectContext. perform {
167+ managedObjectContext. perform {
144168 self . lookupLatest ( identifier: identifier, predicate: predicate) {
145169 switch $0 {
146170 case . success( let object) :
147171 if let object = object {
148- let shouldDelete = block ( object) == . delete
149- do {
150- if shouldDelete {
151- self . managedObjectContext. delete ( object)
152- }
153- try self . managedObjectContext. save ( )
154- self . log. default ( " %{public}@ alert: %{public}@ " , shouldDelete ? " Deleted " : " Recorded " , identifier. value)
155- self . purgeExpired ( )
156- completion ? ( . success)
157- } catch {
158- self . log. error ( " Could not store alert: %{public}@, %{public}@ " , identifier. value, String ( describing: error) )
159- completion ? ( . failure( error) )
160- }
172+ let result = self . update ( objects: [ object] , with: updateBlock)
173+ completion ? ( result)
161174 } else {
162175 self . log. error ( " Alert not found for update: %{public}@ " , identifier. value)
163176 completion ? ( . failure( AlertStoreError . notFound) )
@@ -168,6 +181,41 @@ extension AlertStore {
168181 }
169182 }
170183 }
184+
185+ private func update( objects: [ StoredAlert ] , with updateBlock: @escaping ManagedObjectUpdateBlock ) -> Result < Void , Error > {
186+ objects. forEach { alert in
187+ let shouldDelete = updateBlock ( alert) == . delete
188+ if shouldDelete {
189+ self . managedObjectContext. delete ( alert)
190+ }
191+ self . log. default ( " %{public}@ alert: %{public}@ " , shouldDelete ? " Deleted " : " Recorded " , alert. identifier. value)
192+ }
193+ do {
194+ try self . managedObjectContext. save ( )
195+ } catch {
196+ return . failure( error)
197+ }
198+ self . purgeExpired ( )
199+ return . success
200+ }
201+
202+
203+ private func lookupAll( identifier: Alert . Identifier , predicate: NSPredicate , completion: @escaping ( Result < [ StoredAlert ] , Error > ) -> Void ) {
204+ managedObjectContext. perform {
205+ do {
206+ let fetchRequest : NSFetchRequest < StoredAlert > = StoredAlert . fetchRequest ( )
207+ fetchRequest. predicate = NSCompoundPredicate ( andPredicateWithSubpredicates: [
208+ identifier. equalsPredicate,
209+ predicate
210+ ] )
211+ fetchRequest. fetchLimit = Self . totalFetchLimit
212+ let result = try self . managedObjectContext. fetch ( fetchRequest)
213+ completion ( . success( result) )
214+ } catch {
215+ completion ( . failure( error) )
216+ }
217+ }
218+ }
171219
172220 private func lookupLatest( identifier: Alert . Identifier , predicate: NSPredicate , completion: @escaping ( Result < StoredAlert ? , Error > ) -> Void ) {
173221 managedObjectContext. perform {
0 commit comments