CoreData FetchRequest doesn't update view

I have an app that lets users log drinks. Users create CoreData entries that have attributes like drink type and quantity. I have a view that lets users the quantity they have consumed in the current day. This is done using a FetchRequest and a calendar predicate that only fetches entries from the current day. I am using @FetchRequest property wrapper in the view, then initializing it with init() {}. Inside the initializer, I set the predicate, sort descriptors, and use self._todayIntakeEvents ... to set the value for the fetch request variable. Then, each time the view appears, I use .onAppear to sum the quantity of the fetched items by using todayIntakeEvents.map, then using .reduce to sum the array. The problem: when users add drinks with Siri, the drink information doesn't show up when opening the app from background. However, it will appear if I quit and relaunch the app. What I want to happen is for the drink to appear immediately when the user opens the app again.

My code for the view:

struct TodaySummaryView: View {

    @Environment(\.managedObjectContext) private var viewContext
    @FetchRequest var todayIntakeEvents: FetchedResults<WaterIntakeEvent>

init() {
        let calendar = Calendar.current
        let dateFrom = calendar.startOfDay(for: Date())
        let dateTo = calendar.date(byAdding: .day, value: 1, to: dateFrom)
        let predicateTodayEvents = NSPredicate(format: "timeOfConsumption <= %@ AND timeOfConsumption >= %@", dateTo! as CVarArg, dateFrom as CVarArg)
        self._todayIntakeEvents = FetchRequest(
            entity: WaterIntakeEvent.entity(),
            sortDescriptors: [NSSortDescriptor(keyPath: \WaterIntakeEvent.timeOfConsumption, ascending: false)],
            predicate: predicateTodayEvents)
    }

          var body: some View {
                 // some UI
                      .onAppear {
  totalWaterQuantityToday = todayIntakeEvents.map {Int($0.waterQuantity)}
            sumOfWaterQuantityToday = totalWaterQuantityToday.reduce(0, +)
print(sumOfWaterQuantityToday) // even after Siri creates new CoreData entries, this still prints the quantity from before it added
          }

My code for the Siri Intent Handler:

public func handle(intent: LogDrinkIntent, completion: @escaping (LogDrinkIntentResponse) -> Swift.Void) {
        let context = PersistenceController.shared.container.viewContext
        let newDrink = WaterIntakeEvent(context: context)
        newDrink.drinkType = intent.drinkType
        newDrink.quantity = intent.quantity as! Float
        newDrink.waterQuantity = intent.quantity as! Float
        newDrink.timeOfConsumption = Date()
        newDrink.id = UUID()
        do {
            try context.save()
            let response = LogDrinkIntentResponse(code: LogDrinkIntentResponseCode.success, userActivity: nil)
            completion(response)
            print("Successfully saved.")
        } catch {
            completion(LogDrinkIntentResponse(code: LogDrinkIntentResponseCode.failure, userActivity: nil))
            print("Error saving.")
        }
    }

I suspect the problem is not Siri (because the data appears after relaunching the app) but that because I initialized the view with the FetchRequest, it's not responding to changes. Can someone help please?

I'm a tad tired after a long day's work (it's evening here in Oz) so I haven't really digested what you're doing. However, my first thought is whether you've created a @StateObject to allow your Environment managed object to respond to changes.

I normally put the @StateObject in my SwiftUI app's main (App) scene, and then pass .environment(.managedObjectContext.... to whatever view(s) thereafter need it. This way the resulting views respond immediately to changes in the Managed Object, provided you've used the correct @Environment statement in those views (which you seem to have done).

Good luck and best wishes, Michaela

CoreData FetchRequest doesn't update view
 
 
Q