I have 7 tableviews, one for each day. I add lesson models, with name, starTime, endtime, etc to the day tables, saved to core data. My NSFetchedResultsControlller subclass has 7 instances for each day. It is sorting the entries based on startTime on each table . Everything was working fine on my 0.0, 0.1 of my app. I had a lightweight migration between 0.1, 0.1.1. That only meant adding a new property called "notes (String)". Migration looked successful. Nothing was crashing, everything seemed to work. PROBLEM: Only recently I realized, when I am adding a new entry with a startTime, my fetchedResultsController does not count with the old existing entries. For example I have an older list from two weeks ago, (– probably from before the last app update):
When I am adding a new entry to the list, doesn't matter it has 10:00 startTime, it adds to the end of the line:
however, when I keep adding new entries, they are sorted among the new entries. Let's add an entry with 9:00, what happens is:
So the sorting is working among the new entries. What's even more interesting, sorting is also working among the old entries, so If I change an old entry, for ex. yy to have 13:00, the result is:
But still the new are not considered here.
Anyone has an Idea what can cause this? Is it maybe about my lightweight migration? I think it would be a very bad user experience to reload their tables every time an update is coming. Thanks everyone for taking your time!
UPDATE:
It is probably because an absolute date time is set to my entries, however i just wanted to set a relative time, as my application is a class timetable kind of tool. Maybe the real question is, how to make it independent of actual dates?
my FRC :
import CoreData
class DayFetchedResultsController: NSFetchedResultsController<Lesson> {
override init(fetchRequest: NSFetchRequest<Lesson> = Lesson.fetchRequest(), managedObjectContext context: NSManagedObjectContext = CoreDataManager.shared.persistentContainer.viewContext, sectionNameKeyPath: String? = nil , cacheName name: String? = nil) {
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "startTime", ascending: true)]
super.init(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: sectionNameKeyPath, cacheName: name)
}
func setDayPredicate(_ formatString:String = "dayNumber = %i", day: Int ) {
let predicate = NSPredicate(format: formatString, day)
self.fetchRequest.predicate = predicate
}
func fetch(day: Int) {
setDayPredicate("dayNumber = %i", day: day)
do {
try self.performFetch()
} catch let fetchErr {
print("Failed to fetch results", fetchErr)
}
}
}
on my main VC:
lazy var mondayFetchedResultsController: DayFetchedResultsController = {
let frc = DayFetchedResultsController()
frc.fetch(day: 0)
frc.delegate = self
return frc
}()
lazy var tuesdayFetchedResultsController: DayFetchedResultsController = {
let frc = DayFetchedResultsController()
frc.fetch(day: 1)
frc.delegate = self
return frc
}()
lazy var wednesdayFetchedResultsController: DayFetchedResultsController = {
let frc = DayFetchedResultsController()
frc.fetch(day: 2)
frc.delegate = self
return frc
}()
lazy var thursdayFetchedResultsController: DayFetchedResultsController = {
let frc = DayFetchedResultsController()
frc.fetch(day: 3)
frc.delegate = self
return frc
}()
lazy var fridayFetchedResultsController: DayFetchedResultsController = {
let frc = DayFetchedResultsController()
frc.fetch(day: 4)
frc.delegate = self
return frc
}()
lazy var saturdayFetchedResultsController: DayFetchedResultsController = {
let frc = DayFetchedResultsController()
frc.fetch(day: 5)
frc.delegate = self
return frc
}()
lazy var sundayFetchedResultsController: DayFetchedResultsController = {
let frc = DayFetchedResultsController()
frc.fetch(day: 6)
frc.delegate = self
return frc
}()
Here's what I have found out. I am saving my model objects with a startTime property, like 9:00, but in reality the whole current date is saved together with year, month, day. Console is showing that clearly. That is not what I wanted.
Here' the fix:
I added a new DateComponents() variable. I set its year, month, day to 2001.01.01. Then I let my datePicker set the hours, minutes.
var dateComponents: DateComponents = {
var dc = DateComponents()
dc.year = 2001
dc.month = 1
dc.day = 1
return dc
}()
dateComponents.hour = formatter.calendar.component(.hour, from: datePicker.date)
dateComponents.minute = formatter.calendar.component(.minute, from: datePicker.date)
startTime = formatter.calendar.date(from: dateComponents) ?? Date()