What I want should be simple but for some reason it's not working properly. So, when I rearrange my table view each row is saved in an array friends as a subclass of NSManagedObject in the same order as in the table view(from top to bottom). If the friends view shows two rows, friend1 and friend2, friends[0] is friend1 and friends[1] is friend2.
Whenever the table order has changed, I want the data to be stored in core data in the same order as in the friends array.
Is there any simple way to replace all core data with my friends array?
The default collection type in Core Data is NSSet which is an unordered type.
If you want a standard order like alphabetical, provide an NSSortDescriptor when fetching the data
If you want a custom order add an index field in the data model and assign indexes to the items accordingly. When changing the table view order update the indexes and later fetch the data sorted by index.
If you want to manage an order that has nothing to do with sorted attributes, you can make the relationship "ordered" which will result in the relationship being NSOrderedSet.
You can then manipulate the ordering however you desire, and when you enumerate the collection, it will be in the order you stipulate.
Note, however, that there are some restrictions on NSOrderedSet which are stipulated in the Core Data documentation.
Objects in core data has no order, just like Set.
If you have an entity with to-many relationship with friends, then you can use NSOrderedSet to keep order.
Or, you can set up a property to keep order index as a sort condition when you fetch objects from core data.
Related
I am creating this App which can display some contents in a collection view. The data source of the collection view is stored locally by using CoreData. Each collection view cell will have a corresponding CoreData entity.
Since I am adding a "drag to reorder" feature to the collection view, I need some way to track the order of the CoreData entities. Anyone have any suggestions of how to achieve that?
Appreciate your help!
You may add an integer property to your entity type. Every time you change the order of your entities you assign the current index to this property and save the context after that. You can fetch the entities sorted by this property to restore the order.
But this solution may have two problems:
It may be not performant for large entity sets, and/or frequent updates.
The entity order may not belong to the entity content. This can be problematic, for example, if the data is to be displayed in different views in different order.
In that case you should store the order not with the entities. Instead you can store the order in a property list, e.g. in an array with the identifiers of the entities.
I am writing a demo messaging app to learn Core Data. In my model, an entity Conversation has a to-many relationship messages to Message. A Message has a timeStamp. I intend to display these messages in a collection view/table view with an NSFetchedResultsController. I want to know what would be the most efficient way to sort these messages. I searched around and found that I could sort the messages using:
an NSSortDescriptor on message.timeStamp
making the messages relationship ordered
adding a sequence property to message
What should be the best way to sort the messages?
The sort order should reflect your application logic:
is it logical to move messages inside a conversation? (if yes, sort by sequence number)
Do you want your data to be displayed chronologically? (if yes, sort by timeStamp)
in any case I wouldn't use the ordered relationship as a sort order as you would probably want an FRC to display your data in a table view, and he will manage memory and changes for you.
In addition to that you would want to batch fetch this relationship in any case and not simply let your table view datasource be the ordered set relationship (which will cause the items to be fetch one by one).
I have a managedobject that has a to-many association on it. I want to use a collection of managed objects for the sections in my table, and then the association for the rows. The problem is the association is an NSSet so in cellForRowAtIndexPath: I can't reliably get the position of the sub object I want using the indexPath.row. Has anyone overcome this? Thank you!
You should use an NSFetchedResultsController. It uses sort descriptors to display the
objects in a well-defined order, and with the sectionNameKeyPath: parameter it
can group the objects automatically into sections.
In addition, it updates the table view automatically if objects are inserted, deleted or
changed.
I have this one to many relationship entities. An NSFetchedResultsController was used for a table view to display list of teams. This part I understand and it works fine. Now in this teams table view if one selects a team, another table view will display list of members.
Currently I use an array to hold the objects from the members set, like so:
NSArray *membersList = [NSArray arrayWithArray:[aTeam.members allObjects]];
But this second stage is not clear to me. Should I need to do another NSFetchedResultsController using the selected team name as a fetch predicate for the members list table view instead of expand the fault as I did above?
If you like to track changes in those items (Members), or the data set is very large, you should use a FRC.
If your data is not updated from an external source, and is relatively "small" you could just use the relationship as your datasource.
The FRC is made for you to track changes and access your data in an efficient way (fault and un-fault objects by need, batch fetching ...).
I've been researching this for a while and I think there are a number of solutions, but I'm not sure they are that good. It may be that I've missed something :-)
I have two tables. For each record in TableA there are multiple records in TableB. I.e. a one to many relationship. I've mapped it out in core data and generated the classes. So far so good.
My table view based UI needs to look like this:
Section 1
Cell 1: Table A: field1
Cell 2: Table A: field2
-----
Section 2
Cell 1: Table B: record 1: field1
Cell 2: Table B: record 2: field1
....
When I'm in my tableView:cellForRowAtIndexPath: it's easy to handle section 1 cells because they are different fields from the single Table A record. The section 2 cells are different. Each time tableView:cellForRowAtIndexPath: is called I need to get the correct Table B record from Table A's NSSet. And thats the problem.
NSSet doco indicates that it does not garrantee the order. Which means that if I want a specific record based on an index I have several possible techniques:
Add a sort descriptor to the core data query and use the fast enumeration to get to the record I want. I don't know if this will work because we are still working with an NSSet.
Sort the NSSet using a sort descriptor after getting the data to generate a NSArray and store that in a property before starting the table load.
I'm now thinking of a third option which is to write a decorator for an NSSet which acts like a NSArray and allows me to specify a sort field and automatically tracks changes to the NSSet. Tricky but might pay off in the long run.
neither of these answers seem that great. Is there a better way to do this?
If you just want your objects, use the NSSet accessor.
If you want the object sorted, set up an NSFetchRequest and add the appropriate NSSortDescriptors.
Then, simply perform the fetch with executeFetchRequest:error:
Even better, Since this is specifically for a tableView, use NSFetchedResultsController to populate the table view. That's what it's there for.
I've ended up with a NSArray being stored in the controller and sorting the NSSet records into it.