Beginning Core Data - Part 19: Fetched Results | Ray Wenderlich

The fetched results controller can inform you when your data changes. In this video, you'll learn how to respond to such changes.


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/3444-beginning-core-data/lessons/19

I didn’t understand;
you did same thing on Delete pets instead of using Fetch result controller delegate
Fetch result controller delegate also deleting object
then whats the difference between these two …

I don’t know if it’s me but the final version of the app crashes when addding a friend. Can you provide a final version that works properly so I can correct what is wrong in my version. Thanks.

@vegetarianzombie Can you please help with this when you get a chance? Thank you - much appreciated! :]

I think I found the mistake. You should replace de following code:

func numberOfSections(in collectionView: UICollectionView) -> Int {
    return fetchedRC.fetchedObjects?.count ?? 0
}

with this one:

func numberOfSections(in collectionView: UICollectionView) -> Int {
    return fetchedRC.sections?.count ?? 0
}

Doesn’t look like the threads here are pretty active. But what the hell.

My question is, why did we need to call refresh all the time prior to setting self as a delegate?
if the fetchedRC is suppose to auto update, why is simply collectionView.deleteItems not enough for deleting the items, for example?

Thanks,
Alexander

@alkazakov The video team has been hard at work over the past few weeks on the Android and Kotlin launch on the website. They will be back on the forums soon. Thank you for your patience - much appreciated! :]

Hey There, Thanks for your patience. We’ve been crazy busy.

Regarding your question, the collection view has no idea about the fetched results controller and vice versa. So when you call delete items on the collection view, you’re just removing that item from the collection view (the actual view) while the model itself (core data) still contains that item. Just deleting the item in the collection view means the item still exists in the data store. We’re not actually deleting it. We’re just removing it from the collection view.

That means, when you restart the app, the item will still be there. Hopefully that makes sense. :slight_smile:

Thanks for the response. Great tutorial series.

Thanks so much! I’m glad you are enjoying the videos. Cheers!

I watched the Fetch Request Controller video and was very good. However it show changes made to the PetsView Controller but the downloaded materials has changes on the MainViewController.

Hello, I’ve seen your priceless tutorial videos for CoreData and I’m a big fan of yours :slight_smile:

BTW, I have a question for this last tutorial lecture.
Do you have any sample project for this course that implements insertion/deletion Friend objects using NSFetchedResultsControllerDelegate in MainViewController? I’ve tried to implement this, but this is quite hard for me due to sections .

When I implement insertion/deletion using NSFetchedResultsControllerDelegate and run the app, it crashes when I add a new friend object :frowning: I have no idea why this crash occurs. Do you have an idea or reference that I can refer?

This is the code for insertion/deletion a friend object using NSFetchedResultsControllerDelegate:

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
        switch type {
        case .insert:
            guard let indexPathForInsertion = newIndexPath else {
                return
            }
            if indexPathForInsertion.section > collectionView.numberOfSections - 1 {
                let indexSet = IndexSet(integer: indexPathForInsertion.section)
                collectionView.insertSections(indexSet)
                collectionView.insertItems(at: [indexPathForInsertion])
            }
        case .delete:
            guard let indexPathForDeletion = indexPath else {
                return
            }
            if collectionView.numberOfItems(inSection: indexPathForDeletion.section) == 1 {
                collectionView.deleteSections(IndexSet(integer: indexPathForDeletion.section))
            }
            else {
                collectionView.deleteItems(at: [indexPathForDeletion])
            }
        case .move, .update:
            break
        }
    }

And the error message is:
error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. -[UICachedDeviceRGBColor compare:]: unrecognized selector sent to instance 0x600000261200 with userInfo (null) CoreData: error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. -[UICachedDeviceRGBColor compare:]: unrecognized selector sent to instance 0x600000261200 with userInfo (null)

We didn’t build this out to use inserts and deletes, so this is a great programming exercise that you are doing. Does the message project a location where the error occurred?

I implemented NSFetchedResultsControllerDelegate like this.

The above error happens when a new section is about to be created or the existing section is about to be deleted.

Is that the collection view giving the error, or is it Core Data itself?

I think this error is coming from UICollectionView since the error says:

Assertion failure in -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:animator:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3698.52.10/UICollectionView.m:6015
2018-04-30 21:54:54.032037+0900 PetPal[27601:2067091] [error] error: Serious application error.  Exception was caught during Core Data change processing.  This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification.

This error happens when I delete the only left friend cell in a section.

I am having the same issue.

I haven’t done this with a UICollectionView, but when I’ve done it with a UITableView, I also needed the other function for the delegate, didChange sectionInfo, which is specifically for section changes:

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>,
  didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int,
  for type: NSFetchedResultsChangeType) {

I would suggest you try doing the section changes in that function, and doing only the item inserts and deletes in the didChange anObject function.

I am having the same error