Alexander Khitev
Alexander Khitev

Reputation: 6851

How to make a simple fetch from relationship entities? Swift

I made two relationship entities in Xcode, I use the Swift. I made a simple relationship in Core Data. enter image description here

Company's code

import Foundation
import CoreData

    @objc(Company)
    class Company: NSManagedObject {

        @NSManaged var nameCompany: String
        @NSManaged var additional: NSSet

    }

The additional's code

import Foundation
import CoreData

@objc(Additional)
class Additional: NSManagedObject {

    @NSManaged var acitvityCompany: String
    @NSManaged var founded: String
    @NSManaged var company: Company

}

I wrote a following code which adds data into entities. It works.

       @IBAction func saveData(sender: UIBarButtonItem) {
        var companyEntity = NSEntityDescription.insertNewObjectForEntityForName("Company", inManagedObjectContext: managedObjectContext) as! NSManagedObject
        var additionalEntity = NSEntityDescription.insertNewObjectForEntityForName("Additional", inManagedObjectContext: managedObjectContext) as! NSManagedObject

        companyEntity.setValue(nameCompanyTextField.text, forKey: "nameCompany")

        additionalEntity.setValue(activityTextField.text, forKey: "acitvityCompany")
        additionalEntity.setValue(foundedTextField.text, forKey: "founded")

        companyEntity.setValue(NSSet(object: additionalEntity), forKey: "additional")

        managedObjectContext.save(nil)

        var storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
        var navi = storyboard.instantiateViewControllerWithIdentifier("navi") as! UINavigationController
        self.presentViewController(navi, animated: true, completion: nil)

//        println("company \(companyEntity)")
//        println("additional \(additionalEntity)")
    }

When I move to UITableViewController which shows data from entities. If I fetch data from Additional entity I get an error. CoreData: FATAL ERROR: The persistent cache of section information does not match the current configuration. You have illegally mutated the NSFetchedResultsController's fetch request, its predicate, or its sort descriptor without either disabling caching or using +deleteCacheWithName:

If I fetch data only from Company entity it works good.

My UITableViewController

    override func viewDidLoad() {
    super.viewDidLoad()
    self.definesPresentationContext = true 
    fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest(), managedObjectContext: managedObjectContext, sectionNameKeyPath: "nameCompany", cacheName: "nameCompany")
    fetchedResultsController.delegate = self
    fetchedResultsController.performFetch(nil)

    fetchedResultsController2 = NSFetchedResultsController(fetchRequest: fetchRequest2(), managedObjectContext: managedObjectContext, sectionNameKeyPath: "company", cacheName: "company")
    fetchedResultsController2.delegate = self
    fetchedResultsController2.performFetch(nil)
}

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    self.tableView.reloadData()
}

// MARK: - var and let
var managedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext!

// MARK: - fetchedResultsController
var fetchedResultsController: NSFetchedResultsController!
var fetchedResultsController2: NSFetchedResultsController!

func fetchRequest() -> NSFetchRequest {
    let fetchRequest = NSFetchRequest(entityName: "Company")
    let sortDescriptor = NSSortDescriptor(key: "nameCompany", ascending: true)
    fetchRequest.fetchBatchSize = 50
    fetchRequest.predicate = nil
    fetchRequest.sortDescriptors = [sortDescriptor]
    return fetchRequest
}

func fetchRequest2() -> NSFetchRequest {
    let fetchRequest = NSFetchRequest(entityName: "Additional")
    let sortDescriptor = NSSortDescriptor(key: "company", ascending: true)
    fetchRequest.fetchBatchSize = 50
    fetchRequest.predicate = nil
    fetchRequest.sortDescriptors = [sortDescriptor]
    return fetchRequest
}

 override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return fetchedResultsController.sections?.count ?? 0
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return fetchedResultsController.sections?[section].numberOfObjects ?? 0
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell

    if var dataForCell = fetchedResultsController.objectAtIndexPath(indexPath) as? Company {
        var additionalCell = fetchedResultsController2.objectAtIndexPath(indexPath) as! Additional
        cell.textLabel?.text = dataForCell.nameCompany
        cell.detailTextLabel?.text = "\(additionalCell.acitvityCompany) - \(additionalCell.founded)"
    }

    return cell
}

Upvotes: 0

Views: 911

Answers (1)

Alexander Khitev
Alexander Khitev

Reputation: 6851

I understood how to make it.

var currentDate: NSDate!

    // MARK: - NSFetchedResultsController
    var fetchedResultsController: NSFetchedResultsController!

    func fetchRequest() -> NSFetchRequest {
        let fetchRequest = NSFetchRequest(entityName: "Car")
        let sortDescriptor = NSSortDescriptor(key: "personCar", ascending: true)
        fetchRequest.predicate = NSPredicate(format: "personRelationship.datePerson contains[c] %@", currentDate)
        fetchRequest.fetchBatchSize = 50
        fetchRequest.fetchLimit = 50
        fetchRequest.sortDescriptors = [sortDescriptor]
        println(fetchRequest)
        return fetchRequest
    }

Upvotes: 1

Related Questions