I've encountered a strange issue with FetchRequests that use dynamic predicates generated from passed-down values. The problem is that the FetchRequest updates properly, but the FetchedResults remains the same.
This guy seems to have experienced a similar problem, but the solution doesn't work for me.
Intent and approach
- My Core Data model has 0 or 1 "Day" entry for each day.
- I want to select the date from a custom datepicker and get the corresponding Day entry, displaying its related data.
- So I created a view that takes a
@Binding var dateOffset: Int
and used a custom init to initialize the FetchRequest based on the offset, based on Steve's comment from this SO post
Code
struct DailyStats: View {
@Binding var dayOffset: Int
@Environment(\.managedObjectContext) var context
@FetchRequest<Day> private var days: FetchedResults<Day>
var date: Date
init(dayOffset: Binding<Int>) {
let date = Calendar.current.date(byAdding: DateComponents(day: dayOffset.wrappedValue), to: Date())!
let startOfDay = Calendar.current.startOfDay(for: date)
let startOfNextDay = Calendar.current.date(byAdding: DateComponents(day: 1), to: startOfDay)!
self._days = FetchRequest<Day>(entity: Day.entity(), sortDescriptors: [], predicate: NSPredicate(format: "(date >= %@) AND (date < %@)", startOfDay as NSDate, startOfNextDay as NSDate))
self.date = date
self._dayOffset = dayOffset
}
var body: some View {
VStack {
DayListForFetch(days: days)
if days.first == nil {
Text("no info")
} else {
Text("\(days.first!.wrappedDate, formatter: dateFormat)")
}
I also have a sibling view that actually modifies the dayOffset, but it's pretty trivial.
Results
- Everything up to the FetchRequest updates fine (dayOffset, date, startOfDay, startOfNextDay, and the fetchrequest itself, which I verified by separating the request and results and printing the request)
- Everything after FetchedResults is basically constant. days never changes no matter what I do. However, listening to days.publisher via
onRecieve()
prints "received" every second, so CoreData itself publishes very well. (I have a timer in another tab that writes to CoreData) The view also updates with no problem.
I've tried other methods for dynamic FetchRequests, and I've tried adding State variables so that the view re-renders (although I'm not sure if this was done correctly), nothing works. The view only shows info for today regardless of dayOffset, and the "no info" is never triggered.
Maybe it's a simple mistake or misunderstanding about view updates. Any solution is welcome, even one I've already tried. I'm new to SO, so any advice on SO usage is also welcome.