import CoreData import SwiftUI extension DataTable { final class StateModel: BaseStateModel { @Injected() var broadcaster: Broadcaster! @Injected() var apsManager: APSManager! @Injected() var unlockmanager: UnlockManager! @Injected() private var storage: FileStorage! @Injected() var pumpHistoryStorage: PumpHistoryStorage! @Injected() var healthKitManager: HealthKitManager! let coredataContext = CoreDataStack.shared.viewContext @Published var mode: Mode = .treatments @Published var treatments: [Treatment] = [] @Published var glucose: [Glucose] = [] @Published var meals: [Treatment] = [] @Published var manualGlucose: Decimal = 0 @Published var maxBolus: Decimal = 0 @Published var waitForSuggestion: Bool = false @Published var insulinEntryDeleted: Bool = false @Published var carbEntryDeleted: Bool = false var units: GlucoseUnits = .mmolL override func subscribe() { units = settingsManager.settings.units maxBolus = provider.pumpSettings().maxBolus broadcaster.register(DeterminationObserver.self, observer: self) } @MainActor func invokeGlucoseDeletionTask(_ glucose: GlucoseStored) { Task { do { await deleteGlucose(glucose) } } } func deleteGlucose(_ glucose: GlucoseStored) async { do { coredataContext.delete(glucose) try coredataContext.save() debugPrint( "Data Table State: \(#function) \(DebuggingIdentifiers.succeeded) deleted glucose from core data" ) } catch { debugPrint( "Data Table State: \(#function) \(DebuggingIdentifiers.failed) error while deleting glucose from core data" ) } } @MainActor func invokeCarbDeletionTask(_ treatment: CarbEntryStored) { Task { do { await deleteCarbs(treatment) carbEntryDeleted = true waitForSuggestion = true } } } func deleteCarbs(_ carbEntry: CarbEntryStored) async { do { // TODO: when deleting FPU, do an NSDeleteBatchRequest and remove all entries with same FpuID coredataContext.delete(carbEntry) try coredataContext.save() debugPrint( "Data Table State: \(#function) \(DebuggingIdentifiers.succeeded) deleted carb entry from core data" ) } catch { debugPrint( "Data Table State: \(#function) \(DebuggingIdentifiers.failed) error while deleting carb entry from core data" ) } provider.deleteCarbs(carbEntry) apsManager.determineBasalSync() } @MainActor func invokeInsulinDeletionTask(_ treatment: PumpEventStored) { Task { do { await deleteInsulin(treatment) insulinEntryDeleted = true waitForSuggestion = true } } } func deleteInsulin(_ treatment: PumpEventStored) async { do { let authenticated = try await unlockmanager.unlock() if authenticated { do { coredataContext.delete(treatment) try coredataContext.save() debugPrint( "Data Table State: \(#function) \(DebuggingIdentifiers.succeeded) deleted insulin from core data" ) } catch { debugPrint( "Data Table State: \(#function) \(DebuggingIdentifiers.failed) error while deleting insulin from core data" ) } provider.deleteInsulin(treatment) apsManager.determineBasalSync() } else { print("authentication failed") } } catch { print("authentication error: \(error.localizedDescription)") } } func addManualGlucose() { let glucose = units == .mmolL ? manualGlucose.asMgdL : manualGlucose let glucoseAsInt = Int(glucose) let now = Date() let id = UUID().uuidString let saveToJSON = BloodGlucose( _id: id, direction: nil, date: Decimal(now.timeIntervalSince1970) * 1000, dateString: now, unfiltered: nil, filtered: nil, noise: nil, glucose: Int(glucose), type: GlucoseType.manual.rawValue ) // TODO: -do we need this? // Save to Health var saveToHealth = [BloodGlucose]() saveToHealth.append(saveToJSON) // save to core data let newItem = GlucoseStored(context: coredataContext) newItem.id = UUID() newItem.date = Date() newItem.glucose = Int16(glucoseAsInt) newItem.isManual = true if coredataContext.hasChanges { do { try coredataContext.save() debugPrint( "Data table state model: \(#function) \(CoreDataStack.identifier) \(DebuggingIdentifiers.succeeded) added manual glucose to core data" ) } catch { debugPrint( "Data table state model: \(#function) \(CoreDataStack.identifier) \(DebuggingIdentifiers.failed) failed to add manual glucose to core data" ) } } } } } extension DataTable.StateModel: DeterminationObserver { func determinationDidUpdate(_: Determination) { DispatchQueue.main.async { self.waitForSuggestion = false } } }