NSFetchedResultsController custom behavior upon empty results - ios

I have a single section table view which is hooked up to a NSFetchedResultsController. When the results from the core data is empty and under some extra conditions I would like to create a custom row which contents will be provided not by CoreData. Is there a clean way of implementing this with the NSFetchedResultsController?

No, NSFetchedResultsController does not offer a feature like that. Just implement your table data source to check how many fetchedObjects the FRC has and use that to decide if the rows of the table should be provided by the FRC or you should instead show your custom empty row.

Related

Additional section in UITableView with NSFetchedResultsController

I am currently implementing a UITableViewController with an NSFetchedResultsController. It fetches some objects from CoreData and displays them as rows in one section as expected.
Now, I would like to have one additional section with exactly one row that displays aggregated information about the fetched objects.
From what I know, one NSFetchedResultsController can only have one fetch request, but I would have to use another one to get the aggregated information.
Perhaps I should use one NSFetchedResultsController for the Overall section and another one for the single object section, but this feels kind of strange to me.
What do you think?
You may consider to use one fetchedResultController. And add some observer functions in the delegate of fetchedResultController:
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller{
[self updateAggregatedInformation : basedOnFecthedObjects]; //with collection keypath methods;
[self updateTableView];
}
There is a little overhead in the tableView DataSource, but gain in performance.
I just solved the problem and it was more easy than I thought.
The NSFetchedResultsControllerDelegate receives messages from the FRC and so the delivered IndexPath.section attributes have be adapted according to the tableView. The same needs to be done the other way around when the tableView calls the FRC to create cells that are backed up by the fetched entities.

NSFetchedResultsController per cell in a collectionView

I have a collectionView with NSFetchedResultsController. Some cells in the collectionView will have extra embedded UI elements queried from core data, and those extra embedded UI elements also need the update functionality of NSFetchedResultsController.
So my question is, what is the recommended way of approaching this?
Since the number of cells, and whether or not each of them has embedded UI elements depends on the data actually fetched from server, we cannot use sectionKeyPath of NSFRC right?
EDIT: the extra UI elements are not the same model as the embedding cells and thus require separate queries (NSPredicate).
EDIT: Our core data model:
RelationModel
type
status
Relationships(fromProfile, toProfile)
ProfileModel
..many fields
Relationships(photos)
Basically, the extra UI elements will be toProfiles with the embedding cell being the fromProfile. But because there are more than one kind of relations in the app, we decided to have a separate model for relations. And I found it hard to set a relationship from ProfileModel to the RelationModel
A NSFetchedResultsController is a really cool object. It does a fetch and then monitors core-data for changes. While it has an interface that relies on indexPaths so it is natural to think of these indexPath's as the same indexPaths as your collectionView there is no requirement that you do that. The indexPaths of the fetchedResultsController can be different than the indexPaths of the collectionView - you just need to careful about keeping track which indexPaths you are dealing with and translating from one to the other.
For example: You have a set of widgets that you fetching from core data. Some of the widgets have a property of extraWidgetInfo which you want to display in you UI as an extra cell. The fetchedResultsController says that there are 4 element (all in section 0). But the collectionView can display that as
[section1] widget1,
[section2] widget2, widget 2 extra info,
[section3] widget3,
[section4] widget4, widget 4 extra info.
While the fetchedResultsController only says that there are 4 elements, there are 6 cells in the collectionView. You would also have to translate the fetchedResultsController indexPath when dealing with updates. An update would translate to a reload section, and an add would translate to an insertSection and insert of some amount of rows in that section. You could also just call reloadData when core data updates (If you data is updating rarely this may not be a bad option).
Since we require separate queries in each cell, we ended up setting separate NSFetchedResultsController in each cell when it's dequeued. And then have the NSFetchedResultsController set as nil when prepareForReuse.

Batch update table row, reorder & update at the same time?

Description
I have a CoreData entry called Person, I fetch it using NSFetchedResultsController, with a fetchRequest ordered by property "name". Then I display the "name" in the table view cell.
Problem
When I change the entity's "name" property and the rows reorder, NSFetchedResultsControllerDelegate does give me a NSFetchedResultsChangeType.move. But the "name" displayed on the cell is outdated, meaning I'm not receiving NSFetchedResultsChangeType.update
The Table View Programming Guide: Inserting and Deleting Rows and Sections says batch updates do updates first, then deletions, lastly insertions.
It defers any insertions of rows or sections until after it has handled the deletions of rows or sections. The table view behaves the same way with reloading methods called inside an update blockā€”the reload takes place with respect to the indexes of rows and sections before the animation block is executed. This behavior happens regardless of the ordering of the insertion, deletion, and reloading method calls.
Question
Any idea on how the notifications sent by NSFetchedResultsController are implemented, specifically on the ordering of insert, delete, update & move?
Or how can I use some kind of code to efficiently (meaning partial update, not reload all data) solve this particular problem?
Your setup is non-standard. The sectionNameKeyPath is really meant for sections not rows. Fetch the Person entity and populate the cell with a person's name directly via itemForRowAtIndexPath.
You will then have the expected change types available.

Order entities in Core Data data model

I am using Core Data in my application, and I have entities that need to be reordered. I have a collection view that is populated with NSManagedObjects from the data model, and this collection view can be reordered by dragging and dropping the cells. I want the order of the entities in the data model to reflect the order of the cells in the collection view. Does anyone know how I can accomplish this? I am new to Core Data, so I am still getting used to it.
If I understand your question correctly, you may do it simply as follows:
add an attribute viewOrder to your entity, probably an integer type
update it any time the user drags and drops a cell, i.e. re-orders the collection view (& make sure to save: the NSManagedObjectContext whenever you make any changes)
when populating the collection view, set the NSFetchRequest property sortDescriptors to sort the results by viewOrder
note that if you add new managed objects, you'll have to run a fetch to count the current number in core date or to find the max viewOrder

How to update the UITableViewDataSource when inserting new sections or deleting sections on UITableView?

I've a UITableViewDataSource which maintains sections of data items which will be presented by an UITableView instance. The table view is editable, allowing insertion and deletion of rows and sections, and all changes on the view should be written back to the data source. After reading through the Apple documents, I can deal with insertion and deletion on rows by sending message tableView:commitEditingStyle:forRowAtIndexPath: to the data source.
But, however, I can't figure out what is the standard way to feedback the changes on sections to the data source. Please kindly help.
The delegate method tableView:commitEditingStyle:forRowAtIndexPath: is called by the table view to tell you what the user has done (what they have added / removed). It is then the responsibility of your code to make the appropriate changes to your Model and reload the table view.
The simplest way to reload is to call reloadData, and you also have more specific options for reloading / inserting / removing individual rows or sections - this is all from a UI perspective and the table view requires that you have updated your Model before you call any of these methods or the table view will throw an exception.

Resources