StatStateModel.swift 3.2 KB

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