0

I'm new to swift and I just learned about core data and i am trying to implement it on the project that I currently am working on.

Previously I am taking in a struct

struct Course : Decodable {
let CourseName : String;
let Requirements : String;
}

struct  AllCourses : Decodable {
let ProgramName : String
let Courses : [Course]
}

I tried to create two entities and created a parent-child relationship, I managed to save them, but when I was doing the tableview with section header I could not cause there wasn't a nested array.

How would my attributes and entities be if I want to have a section with Program Name.

Mau
  • 41
  • 4
  • check this following thread https://stackoverflow.com/questions/47990426/how-to-delete-row-in-table-view-core-data-swift-3/48018009#48018009 – Sachin Raut Dec 31 '17 at 13:31
  • Check this following thread https://stackoverflow.com/questions/47990426/how-to-delete-row-in-table-view-core-data-swift-3/48018009#48018009 – Sachin Raut Dec 31 '17 at 13:32

1 Answers1

2

This is the perfect opportunity to use a NSFetchResultsController in combination with your UITableViewController.

Assuming your model has something like this:

Core Data Entity Model

Than your code would look like this:

import UIKit
import CoreData

class ViewController: UITableViewController {

    lazy var fetchedResultsController: NSFetchedResultsController<Course> =    {
        let fetchRequest = NSFetchRequest<Course>(entityName: "Course")
        fetchRequest.sortDescriptors = [NSSortDescriptor(key: "program.name", ascending: true)]

        let moc = *your context*

        let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: moc, sectionNameKeyPath: "program.name", cacheName: nil)
        // controller.delegate = self

        return controller
    }()

    override func numberOfSections(in tableView: UITableView) -> Int {
        guard let sections = self.fetchedResultsController.sections else {
            return 0
        }

        return sections.count
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        guard let sections = self.fetchedResultsController.sections else {
            return 0
        }

        return sections[section].numberOfObjects
    }

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        guard let sections = self.fetchedResultsController.sections else {
            return ""
        }

        return sections[section].indexTitle
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CourseCell") as! UITableViewCell
        cell.course = self.fetchedResultsController.object(at: indexPath)
        return cell
    }
}

When you provide the sectionNameKeyPath to the fetched results controller it will automatically 'group' the results. You could further limit the results by using a predicate on the controller.

richardpiazza
  • 1,487
  • 10
  • 23