Search code examples
swiftcore-dataswift3nsmanagedobjectcontextnsfetchrequest

how to build a dictionary from the fetch request array result?


I have stumbled on setting up a table view with a number of sections based on an entity attribute and the num. of cells based on another attribute of the same entity. I have an entity called Floors (more than one instance can exist) and this has 2 attributes: floor number and number of rooms on the floor. I have performed a fetch request and it return the array. My knowledge is not good enough to figure how to set up a dictionary like this: [floorNumber: numberOfRoomsInFloor] so I can take it and define the number of sections in table and the number of rows in each section. I have tried and failed and I did had a look at threads on the site but I don't really see a solution that could work for me. If someone could take a bit of time and help me out it would mean a lot to me. Please have a look at my code below:

class RoomAndAlarmTypeTableVC: UITableViewController, NSFetchedResultsControllerDelegate {

//MARK: - Properties

private var managedObjectContext: NSManagedObjectContext!

private var storedFloors = [Floors]()

private var floorsAndRooms = [String: String]()

//MARK: - Actions

override func viewDidLoad() {
    super.viewDidLoad()
    managedObjectContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    loadFloorData()
    tableView.delegate = self
    tableView.dataSource = self
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

private func loadFloorData() {
    let floorRequest: NSFetchRequest<Floors> = Floors.fetchRequest()
    do {
        storedFloors = try managedObjectContext.fetch(floorRequest)
        print("\(storedFloors)")

    } catch {
        print("could not load data from core \(error.localizedDescription)")
    }
}



// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
    return storedFloors.count
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    let specificFloor = storedFloors[section]
    return Int(specificFloor.numberOfRooms)
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "house cell", for: indexPath) as! ViewRooomNumberCell
    let tableSections = storedFloors[indexPath.section]
    let floorItem = tableSections.numberOfRooms[indexPath.row]
    let floorNumber = String(floorItem.numberOfRooms)
    cell.floorNumberTxt.text = floorNumber
    return cell
}

}


Solution

  • Assuming that the storedFloors contains all the floors (which are sections) you should not need the dictionary, and just use:

    override func numberOfSections(in tableView: UITableView) -> Int {
        return storedFloors.count
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // this will return the proper number of rows (rooms) for each section
        return storedFloors[section].numberOfRooms
    }