AnnouncementsStorage.swift 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import Foundation
  2. import SwiftDate
  3. import Swinject
  4. protocol AnnouncementsStorage {
  5. func storeAnnouncements(_ announcements: [Announcement], enacted: Bool)
  6. func syncDate() -> Date
  7. func recent() -> Announcement?
  8. }
  9. final class BaseAnnouncementsStorage: AnnouncementsStorage, Injectable {
  10. enum Config {
  11. static let recentInterval = 10.minutes.timeInterval
  12. }
  13. private let processQueue = DispatchQueue(label: "BaseAnnouncementsStorage.processQueue")
  14. @Injected() private var storage: FileStorage!
  15. init(resolver: Resolver) {
  16. injectServices(resolver)
  17. }
  18. func storeAnnouncements(_ announcements: [Announcement], enacted: Bool) {
  19. processQueue.sync {
  20. let file = enacted ? OpenAPS.FreeAPS.announcementsEnacted : OpenAPS.FreeAPS.announcements
  21. self.storage.transaction { storage in
  22. storage.append(announcements, to: file, uniqBy: \.createdAt)
  23. let uniqEvents = storage.retrieve(file, as: [Announcement].self)?
  24. .filter { $0.createdAt.addingTimeInterval(1.days.timeInterval) > Date() }
  25. .sorted { $0.createdAt > $1.createdAt } ?? []
  26. storage.save(Array(uniqEvents), as: file)
  27. }
  28. }
  29. }
  30. func syncDate() -> Date {
  31. guard let events = storage.retrieve(OpenAPS.FreeAPS.announcementsEnacted, as: [Announcement].self),
  32. let recentEnacted = events.filter({ $0.enteredBy == Announcement.remote }).first
  33. else {
  34. return Date().addingTimeInterval(-Config.recentInterval)
  35. }
  36. return recentEnacted.createdAt.addingTimeInterval(Config.recentInterval)
  37. }
  38. func recent() -> Announcement? {
  39. guard let events = storage.retrieve(OpenAPS.FreeAPS.announcements, as: [Announcement].self)
  40. else {
  41. return nil
  42. }
  43. guard let recent = events
  44. .filter({
  45. $0.enteredBy == Announcement.remote && $0.createdAt.addingTimeInterval(Config.recentInterval) > Date()
  46. })
  47. .first
  48. else {
  49. return nil
  50. }
  51. guard let enactedEvents = storage.retrieve(OpenAPS.FreeAPS.announcementsEnacted, as: [Announcement].self)
  52. else {
  53. return recent
  54. }
  55. guard enactedEvents.first(where: { $0.createdAt == recent.createdAt }) == nil
  56. else {
  57. return nil
  58. }
  59. return recent
  60. }
  61. }