Alfredo Pomales
Alfredo Pomales

Reputation: 35

Swift 2: Populating a TableView with two CoreData entities

This is my second question here on the site so any feedback is appreciated in regards to question format. With that being said here's my problem:

I'm trying to populate this tableview with two different CoreData entities and I don't know how to go about that. At first I tried creating another object and doing the necessary methods for the tableview but it didn't work. I'm trying to populate it with data from another entity and I can't get the tableview to display information from the second entity. I'm wondering if there are any known conventions for doing this. Any help is much appreciated.

import UIKit
import CoreData

class DataEntryTableViewController: UITableViewController{

@IBOutlet weak var menuButton: UIBarButtonItem!

@IBOutlet var listaMiembros: UITableView!

var object = [NSManagedObject]()

var dictionary: [String:String] = [
    "tipoVehiculo" :"",
    "ocupantes" :"",
    "numDeTablilla" :"",
    "jurisdiccion": "",
    "estado" :"",
    "vin" :"",
    "year" :"",
    "marca": "",
    "model" :"",
    "marbete" :"",
    "aseguradora" :"",
    "fechaCompra": "",
    "fechaExpiracion": "",
   ]

var objectNum = -1

@IBOutlet weak var listaMembers: UITableViewCell!
override func viewDidLoad() {

  super.viewDidLoad()
  listaMiembros.delegate = self
  listaMiembros.dataSource = self

    // Do any additional setup after loading the view, typically from a nib.
    //ADD SCROLL VIEW DIMENTIONS

    if revealViewController() != nil {
        menuButton.target = revealViewController()
      //  menuButton.action = "revealToggle:"
           menuButton.action = #selector(SWRevealViewController.revealToggle(_:))

        tableView.registerClass(UITableViewCell.self,forCellReuseIdentifier: "Cell")

    }
}

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)

    //1
    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate

    let managedContext = appDelegate.managedObjectContext

    //2       
    let fetchRequest = NSFetchRequest(entityName: "PageFour")

    //3
    do {
        let results = try managedContext.executeFetchRequest(fetchRequest)
        object = results as! [NSManagedObject]
    } catch let error as NSError {
        print("Could not fetch \(error), \(error.userInfo)")
    }

    self.tableView.reloadData()
    objectNum = -1
 }

// MARK: UITableViewDataSource
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return object.count
}

override func tableView(tableView: UITableView,
               cellForRowAtIndexPath
    indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell")
    let person = object[indexPath.row]
    cell!.textLabel!.text = person.valueForKey("numDeTablilla") as? String
   return cell!
}

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let indexPath = tableView.indexPathForSelectedRow // index path of selected cell

    let cellIndex = indexPath!.row // index of selected cell
    // print(indexPath?.row)//iT'S THE NUMBER YOU WANT - 1
    let cellName = tableView.cellForRowAtIndexPath(indexPath!) //  instance of selected cell
    objectNum = cellIndex + 1
    let appDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    let context: NSManagedObjectContext = appDel.managedObjectContext
    let request = NSFetchRequest(entityName: "PageFour")
    request.returnsObjectsAsFaults = false
    do {
        try context.save()
    } catch {
        print("There was a problem!")
    }

    do {
        let results = try context.executeFetchRequest(request)
        if results.count > 0 {

            for result in results as! [NSManagedObject] {

                if cellName?.textLabel?.text == result.valueForKey("numDeTablilla") as? String{

                    dictionary["numDeTablilla"] = result.valueForKey("numDeTablilla") as? String
                    dictionary["marca"] = result.valueForKey("marcaField") as? String
                    dictionary["model"] = result.valueForKey("modeloField") as? String
                    dictionary["year"] = result.valueForKey("yearField") as? String
                    dictionary["tipoVehiculo"] = result.valueForKey("tipoVehiculo") as? String
                    dictionary["ocupantes"] = result.valueForKey("ocupantes") as? String
                    dictionary["jurisdiccion"] = result.valueForKey("jurisdicionVehiculo") as? String
                    dictionary["estado"] = result.valueForKey("estadoField") as? String
                    dictionary["vin"] = result.valueForKey("vinField") as? String
                    dictionary["marbete"] = result.valueForKey("numeroDeMarbete") as? String
                    dictionary["aseguradora"] = result.valueForKey("aseguradoraField") as? String
                    dictionary["fechaCompra"] = result.valueForKey("fechaCompraField") as? String
                    dictionary["fechaExpiracion"] = result.valueForKey("FechaExpiracionField") as? String

                }
            }
            performSegueWithIdentifier("EditVehicle", sender: self)
        }

    } catch {
        print("Fetch Failed")
    }
}

 @IBAction func unwindToVC(segue: UIStoryboardSegue) {
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if (segue.identifier == "EditVehicle"){
        //prepare for segue to the details view controller

        if let detailsVC = segue.destinationViewController as? NewVehicleController {
            // let indexPath = self.tableView.indexPathForSelectedRow

            detailsVC.dictionary = self.dictionary
            detailsVC.objectNum = self.objectNum
        }
    }
    //unnecessary for now
//        if(segue.identifier == "gotoNewData"){
//            if let detailsVC = segue.destinationViewController as?         NewDataEntryTableViewController {
//                //detailsVC.dictionary = self.dictionary
//                detailsVC.objectNum = self.objectNum
//            }
//        }
    self.tableView.reloadData()    
}  
}

Upvotes: 1

Views: 797

Answers (1)

Jon Rose
Jon Rose

Reputation: 8563

First, don't retain managedObjects. If the object is deleted from the database accessing it will cause a crash. It it is better to use a fetchedResultsController that automatically tracks inserts, deletions and changes.

The easiest solution for your problem is to have entities of one type in one section and entities of another type in a different section. (You needn't have a section header so it can appear as one section). You have to have two different fetchedResultsController - one for each section. And you have to be careful to convert your tableview indexPath to the correct fetchedResultsController indexPath - but if you only have two section it is not that hard.

If you want the different entities intersperse between each other that is much harder but it is possible.

Also, I don't know why you are doing a fetch in didSelectRowAtIndexPath that seems wrong. If the data is related to the managedObject at that indexPath you should be able to get any data you need via a relationship.

Upvotes: 1

Related Questions