0

I have been stuck on this error for quite some time now. I have a UITabBar with 2 tabs. The first one contains a UITableViewController with meals on different dates of the week. The second tab contains a UIViewController with a login screen.

The UITableViewController is called 'EettafelView'. It gets it's meals (using Alamofire) from an online source and presents them in the application. They are cached in CoreData and retrieved using a NSFetchedResultsController to present them. For this i'm using the default UITableViewDelegates (numberOfRowsInSection, numberOfSections etc) - If they are relevant i'll post them in an edit.

When the tableview loads and i have set the fetchController and have performed a fetch i pretty-print its objects to test what it holds and if the sort-descriptors have done their job. This leads to the following:

Hollandse stoof met bokbier - Optional("maandag, 20 feb.")
    Gehaktballetjes
    Quorn gehakt
Stamppot van verse spinazie - Optional("dinsdag, 21 feb.")
    Rookworst
    Kaasspies
Indiase Curry - Optional("woensdag, 22 feb.")
    Kip
    Bloemkool
Pasta Mexicane - Optional("donderdag, 23 feb.")
    Gehakt
    Tofu en Bruine Bonen
Boeuf des Gardiens - Optional("vrijdag, 24 feb.")
    Rundvlees
    Kastanjechampignons

With pretty-print code:

if let objects = fetchController?.fetchedObjects as? [Gerecht] {
    for object in objects {
        print("\(object.basis ?? "") - \(object.dateString)")
        print("\t\(object.vlees ?? "")")
        print("\t\(object.vega ?? "")")
    }
}

This is exactly how it is supposed to be. Thus the FetchController holds the right objects and has them sorted correctly. The view however looks likes this:

EettafelView

The section titles are wrong. The code to retrieve the section titles is as follows:

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    if let sections = fetchController?.sections, sections.count > 0 {
        return sections[section].name
    } else {
        return nil
    }
}

Which is I think as generic as it can be. What can be the problem of it retrieving the wrong section titles?

EDIT: - CellForRow Method

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Eettafel") as? Eettafel_Cell
    let gerecht = fetchController?.object(at: indexPath) as? Gerecht
    if let gerecht = gerecht {
        cell?.gerecht = gerecht
    }

    return cell!
}

EDIT - Gerecht in cellForRow

printing the description of the NSManagedObject (breakpoint at if-let gerecht) gives:

Printing description of gerecht.some:
<Almanapp.Gerecht: 0x1740b77c0> (entity: Gerecht; id: 0xd0000000000c0000 <x-coredata://A6B5411D-DF77-43DE-8084-86C76C42F68A/Gerecht/p3> ; data: {
    basis = "Hollandse stoof met bokbier";
    date = "2017-02-20 00:23:07 +0000";
    dateString = "maandag, 20 feb.";
    status = nil;
    vega = "Quorn gehakt";
    vlees = Gehaktballetjes;
})

Which is correct.

Emptyless
  • 2,964
  • 3
  • 20
  • 30
  • Hollandse Stoof met bokbier should be on a monday (maandag) (as per console output) but in the screenshot is on a tuesday (dinsdag) – Emptyless Feb 20 '17 at 00:54
  • Please, change your titleForHeaderInSection for: return fetchController?.sections[section].name And tell me what do you get now – J Manuel Feb 20 '17 at 01:19
  • what are you using for your `sectionNameKeyPath` in your fetchedResultsController? – Jon Rose Feb 20 '17 at 07:05
  • @JuanCurti Didn't make a difference. Still the same as in the screenshot. – Emptyless Feb 20 '17 at 12:47
  • @JonRose I use the sectionNameKeyPath: "dateString" – Emptyless Feb 20 '17 at 12:47
  • @Emptyless Edit your answer and add the cellForRowAtIndexPath function, please – J Manuel Feb 20 '17 at 12:47
  • @JuanCurti added. – Emptyless Feb 20 '17 at 12:49
  • The strangest thing is that when the 'UITableView' reloads is that the titles are placed correctly. But a restart of the app again reverts to the old incorrect behaviour – Emptyless Feb 20 '17 at 12:50
  • I think the problem is in your object. Try debugging your app with a breakpoint on if let gerecht = gerecht {, and see what gerecht has (Check if that is correct). Also see the differences between your cellForRowAtIndexPath and the function you use to reload the tableView. Add it to the post if you want to, and I will help you – J Manuel Feb 20 '17 at 12:51
  • @JuanCurti I have added the 'print description' of 'gerecht' but it holds the right data. The rows are sorted correctly but it is just displaying a random section title like those are not sorted or something. – Emptyless Feb 20 '17 at 12:55
  • @Emptyless Ok. I will add the possible answer – J Manuel Feb 20 '17 at 12:57

2 Answers2

5

You need to add sort descriptor by sectionNameKeyPath for your fetchRequest as FIRST item in array of sort descriptors:

  let request: NSFetchRequest<YourMO> = YourMO.fetchRequest()
    let dateSorting = NSSortDescriptor(key: "date", ascending: true)
    let sectionSorting = NSSortDescriptor(key: "sectionIdentifier", ascending: true)
    request.sortDescriptors = [sectionSorting, dateSorting]
    frc = NSFetchedResultsController(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: "sectionIdentifier", cacheName: nil)
Daniel Smith
  • 720
  • 7
  • 13
2

Try replacing your titleForHeaderInSection function for this.

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
     if let gerecht = fetchController?.object(at: IndexPath(row: 0, section: section)) as? Gerecht {
         return gerecht.dateString 
     }else{ 
         return nil 
     }
}

I think the problem is you were using:

if let sections = fetchController?.sections, sections.count > 0 {
        return sections[section].name

Check that and tell me please

J Manuel
  • 3,010
  • 22
  • 39
  • Changed to: if let gerecht = fetchController?.object(at: IndexPath(row: 0, section: section)) as? Gerecht { return gerecht.dateString } else { return nil } Else it wouldn't compile, but that works – Emptyless Feb 20 '17 at 13:03
  • Yes it works, ill mark it as an answer. But it is still strange how the fetchController sections aren't ordered then. Since it holds the right objects in the right order but somehow the sections aren't ordered the same. – Emptyless Feb 20 '17 at 13:05
  • @Emptyless That's true, I would check how the data is fetched and parsed into a Gerecht object to see if there's any mistake there. – J Manuel Feb 20 '17 at 13:06
  • That's **wrong solution**: secitons contains wrong cells! – Daniel Smith Nov 12 '18 at 07:58