FetchGlucoseManager.swift 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import Combine
  2. import Foundation
  3. import SwiftDate
  4. import Swinject
  5. protocol FetchGlucoseManager {}
  6. final class BaseFetchGlucoseManager: FetchGlucoseManager, Injectable {
  7. private let processQueue = DispatchQueue(label: "BaseGlucoseManager.processQueue")
  8. @Injected() var glucoseStorage: GlucoseStorage!
  9. @Injected() var nightscoutManager: NightscoutManager!
  10. @Injected() var apsManager: APSManager!
  11. @Injected() var settingsManager: SettingsManager!
  12. private var lifetime = Lifetime()
  13. private let timer = DispatchTimer(timeInterval: 1.minutes.timeInterval)
  14. private lazy var appGroupSource = AppGroupSource()
  15. init(resolver: Resolver) {
  16. injectServices(resolver)
  17. subscribe()
  18. }
  19. var glucoseSource: AnyPublisher<[BloodGlucose], Never> {
  20. switch settingsManager.settings.cgm {
  21. case .xdrip:
  22. return appGroupSource.fetch()
  23. default:
  24. return nightscoutManager.fetchGlucose()
  25. }
  26. }
  27. private func subscribe() {
  28. timer.publisher
  29. .receive(on: processQueue)
  30. .flatMap { date -> AnyPublisher<(Date, Date, [BloodGlucose]), Never> in
  31. debug(.nightscout, "FetchGlucoseManager heartbeat")
  32. debug(.nightscout, "Start fetching glucose")
  33. return Publishers.CombineLatest3(
  34. Just(date),
  35. Just(self.glucoseStorage.syncDate()),
  36. self.glucoseSource
  37. )
  38. .eraseToAnyPublisher()
  39. }
  40. .sink { date, syncDate, glucose in
  41. // Because of Spike dosn't respect a date query
  42. let filteredByDate = glucose.filter { $0.dateString > syncDate }
  43. let filtered = self.glucoseStorage.filterTooFrequentGlucose(filteredByDate, at: syncDate)
  44. if !filtered.isEmpty {
  45. debug(.nightscout, "New glucose found")
  46. self.glucoseStorage.storeGlucose(filtered)
  47. self.apsManager.heartbeat(date: date, force: false)
  48. }
  49. }
  50. .store(in: &lifetime)
  51. timer.fire()
  52. timer.resume()
  53. }
  54. }