Search code examples
iosswiftuitableviewcore-datansfetchedresultscontroller

filter NSFetchedResultsController result swift 2


I want automatic updates on tableview..For that i have used NSFetchedResultsControlleras

lazy var fetchedResultsController: NSFetchedResultsController = {
    // Initialize Fetch Request
    let fetchRequest = NSFetchRequest(entityName: "Student")

    // Add Sort Descriptors
    let sortDescriptor = NSSortDescriptor(key: "grade", ascending: true)
    fetchRequest.sortDescriptors = [sortDescriptor]

    // Initialize Fetched Results Controller
    let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)

    // Configure Fetched Results Controller
    fetchedResultsController.delegate = self

    return fetchedResultsController
}()

But i have to filter the results after loading as of user selection as..

  @IBAction func onSegmentValueChanged(sender: UISegmentedControl)
    {
        if sender.selectedSegmentIndex == 0{

            //filter by grade
            let fetchRequest = NSFetchRequest(entityName: "Student")
            let sortDescriptor = NSSortDescriptor(key: "grade", ascending: true)
            fetchRequest.sortDescriptors = [sortDescriptor]
            let filterfetchResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
            let predicate = NSPredicate(format: "address = %@","Russia")
            filterfetchResultsController.fetchRequest.predicate = predicate
            self.tableView.reloadData()

        }else{

            let fetchRequest = NSFetchRequest(entityName: "Student")
            let sortDescriptor = NSSortDescriptor(key: "grade", ascending: true)
            fetchRequest.sortDescriptors = [sortDescriptor]
            let filterfetchResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
            let predicate = NSPredicate(format: "grade = %d",10)
            filterfetchResultsController.fetchRequest.predicate = predicate
            self.tableView.reloadData()


        }

    }

This however reload the tableView but data is not filtered.how do i solve this problem?This is the demo project i am working on.Or should i use the normal way passing the results and reloading tableView as of normal way to solve this problem?


Solution

    1. You must use self.fetchedResultsController, this is your datasource, not filterfetchResultsController: there´s no connection.
    2. You must do a performFetch() to execute the changed predicates

    This works for me:

    @IBAction func onSegmentValueChanged(sender: UISegmentedControl)
    {
        if sender.selectedSegmentIndex == 1{
    
            //filter by address
            let predicate = NSPredicate(format: "address == %@","Russia")
            self.fetchedResultsController.fetchRequest.predicate = predicate
    
        }else{
    
            let predicate = NSPredicate(format: "grade = %d",10)
            self.fetchedResultsController.fetchRequest.predicate = predicate
    
        }
    
        do {
            try self.fetchedResultsController.performFetch()
        } catch {
            let fetchError = error as NSError
            print("\(fetchError), \(fetchError.userInfo)")
        }
        self.tableView.reloadData()
    
    }