swiftcore-datauikitnsfetchedresultscontrollercore-data-migration

My Fetched Results Controller Is Not sorting newer entries among the old entries


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
       }()

Solution

  • 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()