polscm32 2 лет назад
Родитель
Сommit
c5a8f8622e

+ 9 - 1
FreeAPS.xcodeproj/project.pbxproj

@@ -267,6 +267,8 @@
 		45717281F743594AA9D87191 /* ConfigEditorRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 920DDB21E5D0EB813197500D /* ConfigEditorRootView.swift */; };
 		5075C1608E6249A51495C422 /* TargetsEditorProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3BDEA2DC60EDE0A3CA54DC73 /* TargetsEditorProvider.swift */; };
 		53F2382465BF74DB1A967C8B /* PumpConfigProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8630D58BDAD6D9C650B9B39 /* PumpConfigProvider.swift */; };
+		581516A42BCED84A00BF67D7 /* DebuggingIdentifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 581516A32BCED84A00BF67D7 /* DebuggingIdentifiers.swift */; };
+		581516A92BCEEDF800BF67D7 /* NSPredicates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 581516A82BCEEDF800BF67D7 /* NSPredicates.swift */; };
 		587DA1F62B77F3DD00B28F8A /* SettingsRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587DA1F52B77F3DD00B28F8A /* SettingsRowView.swift */; };
 		5BFA1C2208114643B77F8CEB /* AddTempTargetProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEE53A13D26F101B332EFFC8 /* AddTempTargetProvider.swift */; };
 		5D16287A969E64D18CE40E44 /* PumpConfigStateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F60E97100041040446F44E7 /* PumpConfigStateModel.swift */; };
@@ -830,6 +832,8 @@
 		4DD795BA46B193644D48138C /* TargetsEditorRootView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = TargetsEditorRootView.swift; sourceTree = "<group>"; };
 		500371C09F54F89A97D65FDB /* CalibrationsRootView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CalibrationsRootView.swift; sourceTree = "<group>"; };
 		505E09DC17A0C3D0AF4B66FE /* ISFEditorStateModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = ISFEditorStateModel.swift; sourceTree = "<group>"; };
+		581516A32BCED84A00BF67D7 /* DebuggingIdentifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebuggingIdentifiers.swift; sourceTree = "<group>"; };
+		581516A82BCEEDF800BF67D7 /* NSPredicates.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPredicates.swift; sourceTree = "<group>"; };
 		587DA1F52B77F3DD00B28F8A /* SettingsRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsRowView.swift; sourceTree = "<group>"; };
 		5B8A42073A2D03A278914448 /* AddTempTargetDataFlow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = AddTempTargetDataFlow.swift; sourceTree = "<group>"; };
 		5C018D1680307A31C9ED7120 /* CGMStateModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CGMStateModel.swift; sourceTree = "<group>"; };
@@ -1269,12 +1273,12 @@
 				672F63EEAE27400625E14BAD /* AutotuneConfig */,
 				A42F1FEDFFD0DDE00AAD54D3 /* BasalProfileEditor */,
 				3811DE0425C9D32E00A708ED /* Base */,
-				C2C98283C436DB934D7E7994 /* Bolus */,
 				E8176B120B55CE89F1591542 /* Calibrations */,
 				F75CB57ED6971B46F8756083 /* CGM */,
 				0610F7D6D2EC00E3BA1569F0 /* ConfigEditor */,
 				E42231DBF0DBE2B4B92D1B15 /* CREditor */,
 				9E56E3626FAD933385101B76 /* DataTable */,
+				C2C98283C436DB934D7E7994 /* Bolus */,
 				3811DE2725C9D49500A708ED /* Home */,
 				D8F047E14D567F2B5DBEFD96 /* ISFEditor */,
 				C11D545CED3ECEB525EDEE23 /* LibreConfig */,
@@ -1762,6 +1766,7 @@
 				587DA1F52B77F3DD00B28F8A /* SettingsRowView.swift */,
 				BD2FF19F2AE29D43005D1C5D /* CheckboxToggleStyle.swift */,
 				BD1661302B82ADAB00256551 /* CustomProgressView.swift */,
+				581516A32BCED84A00BF67D7 /* DebuggingIdentifiers.swift */,
 			);
 			path = Helpers;
 			sourceTree = "<group>";
@@ -2046,6 +2051,7 @@
 				FEFA5C10299F814A00765C17 /* CoreDataStack.swift */,
 				1956FB202AFF79E200C7B4FF /* CoreDataStorage.swift */,
 				FEFA5C0D299F810B00765C17 /* Core_Data.xcdatamodeld */,
+				581516A82BCEEDF800BF67D7 /* NSPredicates.swift */,
 			);
 			path = Model;
 			sourceTree = "<group>";
@@ -2791,6 +2797,7 @@
 				19D466A729AA2C22004D5F33 /* FPUConfigStateModel.swift in Sources */,
 				38E44528274E401C00EC9A94 /* Protected.swift in Sources */,
 				3811DEB625C9D88300A708ED /* UnlockManager.swift in Sources */,
+				581516A42BCED84A00BF67D7 /* DebuggingIdentifiers.swift in Sources */,
 				E00EEC0827368630002FF094 /* NetworkAssembly.swift in Sources */,
 				38A13D3225E28B4B00EAA382 /* PumpHistoryEvent.swift in Sources */,
 				E00EEC0627368630002FF094 /* UIAssembly.swift in Sources */,
@@ -2857,6 +2864,7 @@
 				FE66D16B291F74F8005D6F77 /* Bundle+Extensions.swift in Sources */,
 				3883581C25EE79BB00E024B2 /* DecimalTextField.swift in Sources */,
 				6B1A8D2E2B156EEF00E76752 /* LiveActivityBridge.swift in Sources */,
+				581516A92BCEEDF800BF67D7 /* NSPredicates.swift in Sources */,
 				38DAB28A260D349500F74C1A /* FetchGlucoseManager.swift in Sources */,
 				38F37828261260DC009DB701 /* Color+Extensions.swift in Sources */,
 				3811DE3F25C9D4A100A708ED /* SettingsStateModel.swift in Sources */,

+ 7 - 0
FreeAPS/Sources/Helpers/DebuggingIdentifiers.swift

@@ -0,0 +1,7 @@
+import Foundation
+
+struct DebuggingIdentifiers {
+    static let succeeded: String = "✅"
+    static let inProgress: String = "⚫️⚫️⚫️"
+    static let failed: String = "❌"
+}

+ 38 - 26
FreeAPS/Sources/Modules/Bolus/BolusStateModel.swift

@@ -94,7 +94,9 @@ extension Bolus {
 
         let now = Date.now
 
-        let coredataContext = CoreDataStack.shared.persistentContainer.viewContext
+        private let treatmentsVM = TreatmentsViewModel()
+
+        let context = CoreDataStack.shared.persistentContainer.viewContext
 
         override func subscribe() {
             setupInsulinRequired()
@@ -340,6 +342,10 @@ extension Bolus {
             }
         }
 
+        // MARK: - Carbs
+
+        // we need to also fetch the data after we have saved them in order to update the array and the UI because of the MVVM Architecture
+
         func addCarbs() {
             guard carbs > 0 || fat > 0 || protein > 0 else { return }
             carbs = min(carbs, maxCarbs)
@@ -359,7 +365,7 @@ extension Bolus {
             carbsStorage.storeCarbs(carbsToStore)
 
             if carbs > 0 {
-                saveToCoreData(carbsToStore)
+                saveCarbsToCoreData(carbsToStore)
 
                 // only perform determine basal sync if the user doesn't use the pump bolus, otherwise the enact bolus func in the APSManger does a sync
                 if amount <= 0 {
@@ -368,10 +374,34 @@ extension Bolus {
             }
         }
 
+        func saveCarbsToCoreData(_: [CarbsEntry]) {
+            context.performAndWait {
+                // create new object in the view context
+                let newCarbEntry = MealsStored(context: self.context)
+                newCarbEntry.id = UUID()
+                newCarbEntry.note = ""
+                newCarbEntry.carbs = Double(carbs)
+                newCarbEntry.fat = Double(fat)
+                newCarbEntry.protein = Double(protein)
+                do {
+                    try self.context.save()
+                    debugPrint(
+                        "Bolus State: \(CoreDataStack.identifier) \(DebuggingIdentifiers.succeeded) saved carbs to core data"
+                    )
+                } catch {
+                    debugPrint(
+                        "Bolus State: \(CoreDataStack.identifier) \(DebuggingIdentifiers.failed) failed to save carbs to core data"
+                    )
+                }
+            }
+        }
+
+        // MARK: - Presets
+
         func deletePreset() {
             if selection != nil {
-                try? coredataContext.delete(selection!)
-                try? coredataContext.save()
+                try? context.delete(selection!)
+                try? context.save()
                 carbs = 0
                 fat = 0
                 protein = 0
@@ -416,9 +446,9 @@ extension Bolus {
             var protein_: Decimal = 0.0
             var presetArray = [Presets]()
 
-            coredataContext.performAndWait {
+            context.performAndWait {
                 let requestPresets = Presets.fetchRequest() as NSFetchRequest<Presets>
-                try? presetArray = coredataContext.fetch(requestPresets)
+                try? presetArray = context.fetch(requestPresets)
             }
             var waitersNotepad = [String]()
             var stringValue = ""
@@ -476,13 +506,13 @@ extension Bolus {
 
         func loadEntries(_ editMode: Bool) {
             if editMode {
-                coredataContext.performAndWait {
+                context.performAndWait {
                     var mealToEdit = [Meals]()
                     let requestMeal = Meals.fetchRequest() as NSFetchRequest<Meals>
                     let sortMeal = NSSortDescriptor(key: "createdAt", ascending: false)
                     requestMeal.sortDescriptors = [sortMeal]
                     requestMeal.fetchLimit = 1
-                    try? mealToEdit = self.coredataContext.fetch(requestMeal)
+                    try? mealToEdit = self.context.fetch(requestMeal)
 
                     self.carbs = Decimal(mealToEdit.first?.carbs ?? 0)
                     self.fat = Decimal(mealToEdit.first?.fat ?? 0)
@@ -493,24 +523,6 @@ extension Bolus {
             }
         }
 
-        func saveToCoreData(_ stored: [CarbsEntry]) {
-            coredataContext.performAndWait {
-                let save = Meals(context: coredataContext)
-                if let entry = stored.first {
-                    save.createdAt = now
-                    save.actualDate = entry.actualDate ?? Date.now
-                    save.id = entry.id ?? ""
-                    save.fpuID = entry.fpuID ?? ""
-                    save.carbs = Double(entry.carbs)
-                    save.fat = Double(entry.fat ?? 0)
-                    save.protein = Double(entry.protein ?? 0)
-                    save.note = entry.note
-                    try? coredataContext.save()
-                }
-                print("meals 1: ID: " + (save.id ?? "").description + " FPU ID: " + (save.fpuID ?? "").description)
-            }
-        }
-
         // MARK: EXTERNAL INSULIN
 
         @MainActor func addExternalInsulin() async {

+ 4 - 4
FreeAPS/Sources/Modules/Home/HomeStateModel.swift

@@ -77,7 +77,7 @@ extension Home {
         @Published var carbsForChart: [CarbsEntry] = []
         @Published var fpusForChart: [CarbsEntry] = []
 
-        let coredataContext = CoreDataStack.shared.persistentContainer.viewContext
+        let context = CoreDataStack.shared.persistentContainer.viewContext
 
         override func subscribe() {
             setupGlucose()
@@ -250,11 +250,11 @@ extension Home {
         }
 
         func cancelProfile() {
-            coredataContext.perform { [self] in
-                let profiles = Override(context: self.coredataContext)
+            context.perform { [self] in
+                let profiles = Override(context: self.context)
                 profiles.enabled = false
                 profiles.date = Date()
-                try? self.coredataContext.save()
+                try? self.context.save()
             }
         }
 

+ 9 - 3
FreeAPS/Sources/Modules/Home/View/Chart/MainChartView.swift

@@ -49,7 +49,6 @@ struct MainChartView: View {
 
     @Binding var glucose: [BloodGlucose]
     @Binding var manualGlucose: [BloodGlucose]
-    @Binding var carbsForChart: [CarbsEntry]
     @Binding var fpusForChart: [CarbsEntry]
     @Binding var units: GlucoseUnits
     @Binding var eventualBG: Int?
@@ -89,6 +88,13 @@ struct MainChartView: View {
     @Environment(\.colorScheme) var colorScheme
     @Environment(\.calendar) var calendar
 
+    // MARK: - Core Data Fetch Requests
+
+    @FetchRequest(
+        entity: MealsStored.entity(),
+        sortDescriptors: [NSSortDescriptor(keyPath: \MealsStored.date, ascending: true)]
+    ) var carbsFromPersistence: FetchedResults<MealsStored>
+
     private var bolusFormatter: NumberFormatter {
         let formatter = NumberFormatter()
         formatter.numberStyle = .decimal
@@ -360,12 +366,12 @@ extension MainChartView {
 
     private func drawCarbs() -> some ChartContent {
         /// carbs
-        ForEach(carbsForChart) { carb in
+        ForEach(carbsFromPersistence) { carb in
             let carbAmount = carb.carbs
             let yPosition = units == .mgdL ? 60 : 3.33
 
             PointMark(
-                x: .value("Time", carb.actualDate ?? Date(), unit: .second),
+                x: .value("Time", carb.date ?? Date(), unit: .second),
                 y: .value("Value", yPosition)
             )
             .symbolSize((Config.carbsSize + CGFloat(carbAmount) * Config.carbsScale) * 10)

+ 0 - 3
FreeAPS/Sources/Modules/Home/View/HomeRootView.swift

@@ -121,9 +121,7 @@ extension Home {
             colorScheme == .dark ? LinearGradient(
                 gradient: Gradient(colors: [
                     Color.bgDarkBlue,
-//                    Color.bgDarkBlue,
                     Color.bgDarkerDarkBlue
-//                    Color.bgDarkBlue
                 ]),
                 startPoint: .top,
                 endPoint: .bottom
@@ -364,7 +362,6 @@ extension Home {
                 MainChartView(
                     glucose: $state.glucose,
                     manualGlucose: $state.manualGlucose,
-                    carbsForChart: $state.carbsForChart,
                     fpusForChart: $state.fpusForChart,
                     units: $state.units,
                     eventualBG: $state.eventualBG,

+ 1 - 0
Model/CoreDataStack.swift

@@ -5,6 +5,7 @@ class CoreDataStack: ObservableObject {
     init() {}
 
     static let shared = CoreDataStack()
+    static let identifier = "CoreDataStack"
 
     lazy var persistentContainer: NSPersistentContainer = {
         let container = NSPersistentContainer(name: "Core_Data")

+ 1 - 1
Model/CoreDataStorage.swift

@@ -4,7 +4,7 @@ import SwiftDate
 import Swinject
 
 final class CoreDataStorage {
-    let coredataContext = CoreDataStack.shared.persistentContainer.viewContext // newBackgroundContext()
+    let coredataContext = CoreDataStack.shared.persistentContainer.viewContext
 
     func fetchGlucose(interval: NSDate) -> [Readings] {
         var fetchGlucose = [Readings]()

+ 8 - 0
Model/Core_Data.xcdatamodeld/Core_Data.xcdatamodel/contents

@@ -83,6 +83,14 @@
         <attribute name="note" optional="YES" attributeType="String"/>
         <attribute name="protein" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
     </entity>
+    <entity name="MealsStored" representedClassName="MealsStored" syncable="YES" codeGenerationType="class">
+        <attribute name="carbs" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
+        <attribute name="date" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
+        <attribute name="fat" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
+        <attribute name="id" optional="YES" attributeType="UUID" usesScalarValueType="NO"/>
+        <attribute name="note" optional="YES" attributeType="String"/>
+        <attribute name="protein" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
+    </entity>
     <entity name="Oref0Suggestion" representedClassName="Oref0Suggestion" syncable="YES" codeGenerationType="class">
         <relationship name="computedInsulinDistribution" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="InsulinDistribution" inverseName="insulin" inverseEntity="InsulinDistribution"/>
         <relationship name="computedTDD" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="TDD" inverseName="computed" inverseEntity="TDD"/>

+ 24 - 0
Model/NSPredicates.swift

@@ -0,0 +1,24 @@
+import CoreData
+import Foundation
+
+extension Date {
+    static var oneDayAgo: Date {
+        Calendar.current.date(byAdding: .day, value: -1, to: Date())!
+    }
+
+    static var halfHourAgo: Date {
+        Calendar.current.date(byAdding: .minute, value: -30, to: Date())!
+    }
+}
+
+extension NSPredicate {
+    static var predicateForOneDayAgo: NSPredicate {
+        let date = Date.oneDayAgo
+        return NSPredicate(format: "date >= %@", date as NSDate)
+    }
+
+    static var predicateFor30MinAgo: NSPredicate {
+        let date = Date.halfHourAgo
+        return NSPredicate(format: "date > %@", date as NSDate)
+    }
+}