Hello Everyone. I am new to Core Data and I am having a strange issue when adding a new entity entry when I try to add a child entity at the same time. I am trying to create a new Project Entity and adding a Feature Entity at the same time. When I save the addition it tries to reload the table data but throws an error because there is a second Project Entity that was created with a nil projectName and projectDate. If I comment out the add of the Feature Entity everything works fine. Any ideas?
import UIKit
import CoreData
class ProjectTableViewController: UITableViewController, NSFetchedResultsControllerDelegate {
var managedObjectContext: NSManagedObjectContext? = nil
override func viewDidLoad() {
super.viewDidLoad()
/
/
/
/
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
/
}
@IBAction func addProject(_ sender: AnyObject){
let alert = UIAlertController(title: "New Project",
message: "Add a new project",
preferredStyle: .alert)
let saveAction = UIAlertAction(title: "Save",
style: .default,
handler: { (action:UIAlertAction) -> Void in
let context = self.fetchedResultsController.managedObjectContext
/
let newProject = SSProjectMO(context: context)
/
let textField = alert.textFields!.first
newProject.projectName = textField!.text!
newProject.projectDate = NSDate();
let newItem = NSEntityDescription.insertNewObject(forEntityName: "Feature", into: context) as! SSFeatureMO
newItem.featureName = "High Challenge Course"
newProject.addToProjectRelationship(newItem)
print("Saving with Date \(newProject.projectDate)")
/
do {
/
try context.save()
} catch {
/
/
print("Error Saving Project")
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
self._fetchedResultsController = nil
self.tableView.reloadData()
})
let cancelAction = UIAlertAction(title: "Cancel",
style: .default) { (action: UIAlertAction) -> Void in
}
alert.addTextField {
(textField: UITextField) -> Void in
}
alert.addAction(saveAction)
alert.addAction(cancelAction)
present(alert,
animated: true,
completion: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showFeatures" {
if let indexPath = self.tableView.indexPathForSelectedRow {
let object = self.fetchedResultsController.object(at: indexPath)
let controller = (segue.destination as! UINavigationController).topViewController as! MasterViewController
controller.projectItem = object
controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem
controller.navigationItem.leftItemsSupplementBackButton = true
/
/
/
/
/
}
}
}
/
override func numberOfSections(in tableView: UITableView) -> Int {
return self.fetchedResultsController.sections?.count ?? 0
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let sectionInfo = self.fetchedResultsController.sections![section]
print("Number of object \(sectionInfo.numberOfObjects)")
return sectionInfo.numberOfObjects
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as? ProjectTableViewCell
let event = self.fetchedResultsController.object(at: indexPath)
print("New Cell \(event.projectName) and date \(event.projectDate) and feature count \(event.projectRelationship?.count)")
cell?.projectTitle.text = event.projectName
let formatter = DateFormatter();
formatter.dateFormat = "yyyy-MM-dd";
cell?.projectDate.text = formatter.string(from: event.projectDate as! Date)
return cell!
}
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
/
return true
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
let context = self.fetchedResultsController.managedObjectContext
context.delete(self.fetchedResultsController.object(at: indexPath))
do {
try context.save()
} catch {
/
/
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
self._fetchedResultsController = nil
self.tableView.reloadData()
}
}
func configureCell(_ cell: UITableViewCell, withEvent event: SSProjectMO) {
cell.textLabel!.text = event.projectName!.description
/
}
var fetchedResultsController: NSFetchedResultsController<SSProjectMO> {
if _fetchedResultsController != nil {
return _fetchedResultsController!
}
let fetchRequest: NSFetchRequest<SSProjectMO> = SSProjectMO.fetchRequest()
/
fetchRequest.fetchBatchSize = 20
/
let sortDescriptor = NSSortDescriptor(key: "projectName", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
/
/
let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!, sectionNameKeyPath: nil, cacheName:nil)
aFetchedResultsController.delegate = self
_fetchedResultsController = aFetchedResultsController
do {
try _fetchedResultsController!.performFetch()
} catch {
/
/
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
return _fetchedResultsController!
}
var _fetchedResultsController: NSFetchedResultsController<SSProjectMO>? = nil
}