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?