DataTableStateModel.swift 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import CoreData
  2. import SwiftUI
  3. extension DataTable {
  4. final class StateModel: BaseStateModel<Provider> {
  5. @Injected() var broadcaster: Broadcaster!
  6. @Injected() var apsManager: APSManager!
  7. @Injected() var unlockmanager: UnlockManager!
  8. @Injected() private var storage: FileStorage!
  9. @Injected() var pumpHistoryStorage: PumpHistoryStorage!
  10. @Injected() var healthKitManager: HealthKitManager!
  11. let coredataContext = CoreDataStack.shared.viewContext
  12. @Published var mode: Mode = .treatments
  13. @Published var treatments: [Treatment] = []
  14. @Published var glucose: [Glucose] = []
  15. @Published var meals: [Treatment] = []
  16. @Published var manualGlucose: Decimal = 0
  17. @Published var maxBolus: Decimal = 0
  18. @Published var waitForSuggestion: Bool = false
  19. @Published var insulinEntryDeleted: Bool = false
  20. @Published var carbEntryDeleted: Bool = false
  21. var units: GlucoseUnits = .mmolL
  22. override func subscribe() {
  23. units = settingsManager.settings.units
  24. maxBolus = provider.pumpSettings().maxBolus
  25. broadcaster.register(DeterminationObserver.self, observer: self)
  26. }
  27. @MainActor func invokeGlucoseDeletionTask(_ glucose: GlucoseStored) {
  28. Task {
  29. do {
  30. await deleteGlucose(glucose)
  31. }
  32. }
  33. }
  34. func deleteGlucose(_ glucose: GlucoseStored) async {
  35. do {
  36. coredataContext.delete(glucose)
  37. try coredataContext.save()
  38. debugPrint(
  39. "Data Table State: \(#function) \(DebuggingIdentifiers.succeeded) deleted glucose from core data"
  40. )
  41. } catch {
  42. debugPrint(
  43. "Data Table State: \(#function) \(DebuggingIdentifiers.failed) error while deleting glucose from core data"
  44. )
  45. }
  46. }
  47. @MainActor func invokeCarbDeletionTask(_ treatment: CarbEntryStored) {
  48. Task {
  49. do {
  50. await deleteCarbs(treatment)
  51. carbEntryDeleted = true
  52. waitForSuggestion = true
  53. }
  54. }
  55. }
  56. func deleteCarbs(_ carbEntry: CarbEntryStored) async {
  57. do {
  58. // TODO: when deleting FPU, do an NSDeleteBatchRequest and remove all entries with same FpuID
  59. coredataContext.delete(carbEntry)
  60. try coredataContext.save()
  61. debugPrint(
  62. "Data Table State: \(#function) \(DebuggingIdentifiers.succeeded) deleted carb entry from core data"
  63. )
  64. } catch {
  65. debugPrint(
  66. "Data Table State: \(#function) \(DebuggingIdentifiers.failed) error while deleting carb entry from core data"
  67. )
  68. }
  69. provider.deleteCarbs(carbEntry)
  70. apsManager.determineBasalSync()
  71. }
  72. @MainActor func invokeInsulinDeletionTask(_ treatment: PumpEventStored) {
  73. Task {
  74. do {
  75. await deleteInsulin(treatment)
  76. insulinEntryDeleted = true
  77. waitForSuggestion = true
  78. }
  79. }
  80. }
  81. func deleteInsulin(_ treatment: PumpEventStored) async {
  82. do {
  83. let authenticated = try await unlockmanager.unlock()
  84. if authenticated {
  85. do {
  86. coredataContext.delete(treatment)
  87. try coredataContext.save()
  88. debugPrint(
  89. "Data Table State: \(#function) \(DebuggingIdentifiers.succeeded) deleted insulin from core data"
  90. )
  91. } catch {
  92. debugPrint(
  93. "Data Table State: \(#function) \(DebuggingIdentifiers.failed) error while deleting insulin from core data"
  94. )
  95. }
  96. provider.deleteInsulin(treatment)
  97. apsManager.determineBasalSync()
  98. } else {
  99. print("authentication failed")
  100. }
  101. } catch {
  102. print("authentication error: \(error.localizedDescription)")
  103. }
  104. }
  105. func addManualGlucose() {
  106. let glucose = units == .mmolL ? manualGlucose.asMgdL : manualGlucose
  107. let glucoseAsInt = Int(glucose)
  108. let now = Date()
  109. let id = UUID().uuidString
  110. let saveToJSON = BloodGlucose(
  111. _id: id,
  112. direction: nil,
  113. date: Decimal(now.timeIntervalSince1970) * 1000,
  114. dateString: now,
  115. unfiltered: nil,
  116. filtered: nil,
  117. noise: nil,
  118. glucose: Int(glucose),
  119. type: GlucoseType.manual.rawValue
  120. )
  121. // TODO: -do we need this?
  122. // Save to Health
  123. var saveToHealth = [BloodGlucose]()
  124. saveToHealth.append(saveToJSON)
  125. // save to core data
  126. let newItem = GlucoseStored(context: coredataContext)
  127. newItem.id = UUID()
  128. newItem.date = Date()
  129. newItem.glucose = Int16(glucoseAsInt)
  130. newItem.isManual = true
  131. if coredataContext.hasChanges {
  132. do {
  133. try coredataContext.save()
  134. debugPrint(
  135. "Data table state model: \(#function) \(CoreDataStack.identifier) \(DebuggingIdentifiers.succeeded) added manual glucose to core data"
  136. )
  137. } catch {
  138. debugPrint(
  139. "Data table state model: \(#function) \(CoreDataStack.identifier) \(DebuggingIdentifiers.failed) failed to add manual glucose to core data"
  140. )
  141. }
  142. }
  143. }
  144. }
  145. }
  146. extension DataTable.StateModel: DeterminationObserver {
  147. func determinationDidUpdate(_: Determination) {
  148. DispatchQueue.main.async {
  149. self.waitForSuggestion = false
  150. }
  151. }
  152. }