FetchTreatmentsManager.swift 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import Combine
  2. import CoreData
  3. import Foundation
  4. import SwiftDate
  5. import Swinject
  6. protocol FetchTreatmentsManager {}
  7. final class BaseFetchTreatmentsManager: FetchTreatmentsManager, Injectable {
  8. private let processQueue = DispatchQueue(label: "BaseFetchTreatmentsManager.processQueue")
  9. @Injected() var nightscoutManager: NightscoutManager!
  10. @Injected() var tempTargetsStorage: TempTargetsStorage!
  11. @Injected() var carbsStorage: CarbsStorage!
  12. private var lifetime = Lifetime()
  13. private let timer = DispatchTimer(timeInterval: 1.minutes.timeInterval)
  14. private var backgroundContext = CoreDataStack.shared.newTaskContext()
  15. init(resolver: Resolver) {
  16. injectServices(resolver)
  17. subscribe()
  18. }
  19. private func subscribe() {
  20. timer.publisher
  21. .receive(on: processQueue)
  22. .sink { [weak self] _ in
  23. guard let self = self else { return }
  24. debug(.nightscout, "FetchTreatmentsManager heartbeat")
  25. debug(.nightscout, "Start fetching carbs and temptargets")
  26. Task {
  27. // Fetch carbs and temp targets concurrently
  28. async let carbs = self.nightscoutManager.fetchCarbs()
  29. async let tempTargets = self.nightscoutManager.fetchTempTargets()
  30. // Filter and store if not from "Trio"
  31. let filteredCarbs = await carbs.filter { $0.enteredBy != CarbsEntry.local }
  32. if filteredCarbs.isNotEmpty {
  33. await self.carbsStorage.storeCarbs(filteredCarbs, areFetchedFromRemote: true)
  34. }
  35. // Filter and store if not from Trio
  36. let filteredTargets = await tempTargets.filter { $0.enteredBy != TempTarget.local }
  37. if filteredTargets.isNotEmpty {
  38. // Sort temp targets by creation date
  39. let sortedTargets = filteredTargets.sorted { $0.createdAt < $1.createdAt }
  40. // Iterate and store each temp target
  41. for (index, tempTarget) in sortedTargets.enumerated() {
  42. // Skip saving if a Temp Target with the same date already exists or it's a cancel target
  43. guard await !self.tempTargetsStorage.existsTempTarget(with: tempTarget.createdAt),
  44. tempTarget.reason != TempTarget.cancel
  45. else {
  46. debug(
  47. .nightscout,
  48. "Skipping temp target with date: \(tempTarget.date ?? Date.distantPast)"
  49. )
  50. continue
  51. }
  52. // Create a mutable copy and set enabled for the last temp target
  53. var mutableTempTarget = tempTarget
  54. mutableTempTarget.enabled = (index == sortedTargets.count - 1)
  55. // Save to Core Data
  56. await self.tempTargetsStorage.storeTempTarget(tempTarget: mutableTempTarget)
  57. }
  58. // Save the temp targets to JSON so that they get used by oref
  59. self.tempTargetsStorage.saveTempTargetsToStorage(sortedTargets)
  60. // Update Adjustments View
  61. Foundation.NotificationCenter.default.post(name: .didUpdateTempTargetConfiguration, object: nil)
  62. }
  63. }
  64. }
  65. .store(in: &lifetime)
  66. timer.fire()
  67. timer.resume()
  68. }
  69. }