I am learning coreData
and I am new it, I have created a one-to-many relationship of boss and employee, (i.e one boss and many employees). So I am showing all the bosses on firstTableView
and when the user clicks on the cells, he can view the employees assigned to each boss and also he can add employees to any particular boss. Now I want to reorder the boss cells. So how it should be done?
Edited based on the discussion below
- (void)insertNewObject:(NSString *)fileName
{
Boss *bossName = [NSEntityDescription insertNewObjectForEntityForName:@"Boss" inManagedObjectContext:self.managedObjectContext];
[bossName setName:fileName];
NSManagedObject *lastObject = [self.controller.fetchedObjects lastObject];
float lastObjectDisplayOrder = [[lastObject valueForKey:@"displayOrder"] floatValue];
NSLog(@"%f",lastObjectDisplayOrder);
[bossName setValue:[NSNumber numberWithDouble:lastObjectDisplayOrder + 1.0] forKey:@"displayOrder"];
// Save the context.
NSError *error = nil;
if (![self.managedObjectContext save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
[Specific Answer To Updated Question]
It would be either ....
[self.boss insertObject:newEmployeeObject inEmployeesAtIndex:0];
Which is a core-data generated method that is part of your Boss subclass if you choose to create subclasses from your model. Or....
NSMutableOrderedSet *employees = [self.boss mutableOrderedSetValueForKey:@"employees"];
[employees insertObject:newEmployee atIndex:0]
It's not that intuitive I know, you can't just make a mutable copy, you have to get a special proxy object from mutableOrderedSetValueForKey
.
[Original General Answer]...
Core-data now has the ability to use "Ordered Relationships" which you can specify in your model. If you do so, relationships in your object model will be represented by a new class NSOrderedSet
which is a hybrid of an NSArray
and an NSSet
. By re-ordering the objects in this relationship object and saving the context you will reorder the objects in the database and they will maintain their new order. This kind of ordered relationship tends to be used when there isn't natural ordering attribute on the object. For instance the order simply represents the users preference for ordering a list in the UI.
If on the other hand you have an attribute on one of your objects that describes the order for a collection then you can use that attribute to order the results of an NSFetchRequest by specifying the Sort Descriptors
. The value of the attribute would specify the position the object would be in in the results of the NSFetchRequest
.
If you are using Ordered Relationships
you would need keep the order of the NSOrderedSet
for that relationship and the UITableView
in sync. If the change was driven from the UI then you respond to the UITableViewDataSource
delegate methods such as - (void)moveRowAtIndex:(NSUInteger)sourceIndex toIndex:(NSUInteger)destinationIndex
and use the information provided to move the corresponding object to it's new position in the core-data relationship either by using the proxy object from mutableOrderedSetValueForKey:
or the Core-data generated accessors of a generated subclass.
If the change to order were driven from the data side you would use the methods on UITableView
such as insertRowsAtIndexPaths:withRowAnimation:
and moveRowAtIndexPath:toIndexPath:
to sync the rows in the UITableView
with the changes you were making in the data.
If you are using NSFetchRequest
s you have a similar task. In this case you respond to user driven changes in the order by updating the sort attributes on your objects to match the new order that is described by the UITableView
through the UITableViewDataSource
delegate. Or if the ordering changes are starting at the data side you update the UITableView
through it's methods to match the changes you are making to the sort attributes on the data. In this case you will be working with the results from the NSFetchResults
as an NSArray
, you would also have to keep that object in sync until the next time you ran the NSFetchRequest
. You could use the same sort descriptor to sort the array, or create an NSMutableArray
and use it's methods to move the data to match the table.
Finally if you are using NSFetchRequest
you may like to look at NSFetchedResultsController
It's job it is to simplify task of syncing a sorted NSFetchRequest
and a UITableView
. There is good sample code for this in the documentation. In this case you may find that the ordering of the data will take care of itself. For instance say your table is ordered by "assignment date" (i.e. the date at which an employee was assigned to a boss) then simply creating the objects with the correct information would trigger the correct results in the table.
Please note that ordered relationships do not work with iCloud. However in my opinion iCloud doesn't work anyway so that's not a problem.