Order entities in Core Data data model - ios

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

Related

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.

Any way to group items by property in UITableView in runtime?

I have a UITableView which I populate by a list of objects I'm getting from a Realm database. What I want to do is to create sections and group items in the list by a property value in runtime.
All of the examples of grouping items in UITableView I see online are operating with it a prearranged dictionaries.
Is it possible to do?
You can set up your table view data source any way you want. You could write code that decides on the fly which items belong in which sections, but I would advise against it.
I would suggest setting up a method that takes your list of Realm objects as input, and builds an array of sections containing sub-arrays of the rows. Then your cellForRowAtIndexPath method can simply index into your model data like normal.

Core data - How to reload NSSet (child objects) on second tableview controller

Hi I am new to Core data. I am having difficulties in reloading my child objects or the NSSet objects which is located on a second tableview.
So I have two tableview controllers, the first one is Budget where I can add or delete a budget. Within that budget object it has a one to many relationship with Expense object (So the Expense is the NSSet).
After when I tap into one of the budget cells, it takes me to the NSSet of Expenses, I then converted the Expenses NSSet into NSArray by using the allObjects method like below:
_expenses = [[_currentBudget expenses]allObjects];
I then populated the table view controller and it shows me all of the individual expense available within that budget. I then have an add (+) bar button to add an expense into the current budget (or call the predefined method that core data gave me: -(void)addExpensesObject(NSManagedObject*)object
Everything is great and it can be saved. However.... once I saved I am not sure how to reload the NSArray of expenses as it is not like the fetchedResultsController. (I am able to reload data on the first tablview once a budget was added because i used the NSFetchedResultsControllerDelegate and implemented the changes/update/insert etc methods).
So my question is, how do I reload those set of NSArray objects? I tried to add in viewdidappear [[self tableview]reloadData] but that didn't work for some reason.. But when I tap back to the first tableview (budgets) and tap back into the expense... it reloads.
Many thanks!
The simplest solution would probably be to use a fetched results controller in the
second table view controller as well. Instead of passing
[[_currentBudget expenses]allObjects]
to the second view controller, just pass _currentBudget. In the second view
controller, create a fetched results controller with a
fetch request on the "Expense" entity and using a predicate like
[NSPredicate predicateWithFormat:#"budget = %#", self.currentBudget]

Sorting with Core Data attribute

I have a UITableView that is populated with table view cells from an NSFetchedResultsController. Each table view cell is linked to an entity object under Core Data.
I recently performed a lightweight migration and added an attribute that every entity object should have. The problem is, I am not sure how to apply it to the existing table view cells.
To be more specific, I want to add an orderingValue attribute to each object (task) that is linked to a table view cell. How would I make this orderingValue equal to the indexPath.row of the tableviewcell?

NSFetchedResultsController custom behavior upon empty results

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.

Resources