StatStateModel.swift 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. import CoreData
  2. import Foundation
  3. import Observation
  4. import SwiftUI
  5. import Swinject
  6. extension Stat {
  7. @Observable final class StateModel: BaseStateModel<Provider> {
  8. @ObservationIgnored @Injected() var settings: SettingsManager!
  9. var highLimit: Decimal = 10 / 0.0555
  10. var lowLimit: Decimal = 4 / 0.0555
  11. var overrideUnit: Bool = false
  12. var layingChart: Bool = false
  13. var units: GlucoseUnits = .mgdL
  14. var glucoseFromPersistence: [GlucoseStored] = []
  15. var selectedDuration: Duration = .Today
  16. private let context = CoreDataStack.shared.newTaskContext()
  17. private let viewContext = CoreDataStack.shared.persistentContainer.viewContext
  18. enum Duration: String, CaseIterable, Identifiable {
  19. case Today
  20. case Day
  21. case Week
  22. case Month
  23. case Total
  24. var id: Self { self }
  25. }
  26. override func subscribe() {
  27. /// Default is today
  28. setupGlucoseArray(for: .Today)
  29. highLimit = settingsManager.settings.high
  30. lowLimit = settingsManager.settings.low
  31. units = settingsManager.settings.units
  32. overrideUnit = settingsManager.settings.overrideHbA1cUnit
  33. layingChart = settingsManager.settings.oneDimensionalGraph
  34. }
  35. func setupGlucoseArray(for duration: Duration) {
  36. Task {
  37. let ids = await self.fetchGlucose(for: duration)
  38. await updateGlucoseArray(with: ids)
  39. }
  40. }
  41. private func fetchGlucose(for duration: Duration) async -> [NSManagedObjectID] {
  42. let predicate: NSPredicate
  43. switch duration {
  44. case .Day:
  45. predicate = NSPredicate.glucoseForStatsDay
  46. case .Week:
  47. predicate = NSPredicate.glucoseForStatsWeek
  48. case .Today:
  49. predicate = NSPredicate.glucoseForStatsToday
  50. case .Month:
  51. predicate = NSPredicate.glucoseForStatsMonth
  52. case .Total:
  53. predicate = NSPredicate.glucoseForStatsTotal
  54. }
  55. let results = await CoreDataStack.shared.fetchEntitiesAsync(
  56. ofType: GlucoseStored.self,
  57. onContext: context,
  58. predicate: predicate,
  59. key: "date",
  60. ascending: false,
  61. batchSize: 100,
  62. propertiesToFetch: ["glucose", "objectID"]
  63. )
  64. return await context.perform {
  65. guard let fetchedResults = results as? [[String: Any]] else { return [] }
  66. return fetchedResults.compactMap { $0["objectID"] as? NSManagedObjectID }
  67. }
  68. }
  69. @MainActor private func updateGlucoseArray(with IDs: [NSManagedObjectID]) {
  70. do {
  71. let glucoseObjects = try IDs.compactMap { id in
  72. try viewContext.existingObject(with: id) as? GlucoseStored
  73. }
  74. glucoseFromPersistence = glucoseObjects
  75. } catch {
  76. debugPrint(
  77. "Home State: \(#function) \(DebuggingIdentifiers.failed) error while updating the glucose array: \(error.localizedDescription)"
  78. )
  79. }
  80. }
  81. }
  82. }