CoreData: sort items by index in set category

I have a simple directory manager function with items in categories EXCEPT a single item can be in several categories.

The item has a parent key, which is the NSSet of the parent categories

The category has a "items" key, which is NSOrderedSet for its subelements

I am using NSFetchedResultController and its delegate to populate my table with elements

 NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:self.managedObjectContext]; [fetchRequest setEntity:entity]; fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(ANY parents == %@)", self.category]; [fetchRequest setFetchBatchSize:30]; [fetchRequest setSortDescriptors:@[????????]; NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil]; aFetchedResultsController.delegate = self; self.fetchedResultsController = aFetchedResultsController; NSError *error = nil; if (![self.fetchedResultsController performFetch:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } 

Therefore, using this code, I can get a list of elements in self.category

My user interface has Drag and Drop functionality. Therefore, I can move elements within categories.

My question: In categories 1 and 2, there are links to the same elements as Item1 and Item2. I need to have Item1, Item2 order in Class1 and Item2, Item1 order in Category2. So I made the property category.items as NSOrderedSet .

But I just can't sort the items by their index in category.items

I tried to use blocks in sorting descriptors - it did not work, I tried to use a selector in sorting descriptors - did not work, I tried to describe class descriptors - it works somehow, but does not update the elements when I change their index in a category. Like this in my NSSortDescriptorSubclass:

- (NSComparisonResult)compareObject:(Item*)object1 toObject:(Item*)object2 {

 int index1 = [self.category.items indexOfObject:object1]; int index2 = [self.category.items indexOfObject:object2]; if (index1 > index2) { return NSOrderedDescending; } else if (index1 < index2) { return NSOrderedAscending; } return NSOrderedSame; 

} Code> But the order of the elements will not be updated in my user interface if I change the order in Category.items

So please help me sort the items by their index in the category. Perhaps there is a way to do this through some keys, operators, expressions, something else. Thanks.

+3
sorting ios core-data
source share
2 answers

I recommend that you do not use relationships that are ordered in many ways. They do not seem to work properly and do not fit your needs.

Instead, you need to enter your own attribute for sorting. You can have a categoryItem entity that has one to one relationship with both Category and Item , as well as with the sequence attribute.

In your FRC, you get a categoryItem object, and when displayed, you simply use categoryItem.item to access the properties of the element. When you reorder (for example, using drag and drop), you must renumber all categoryItem and assign the correct serial number.

- EDIT -

To mark categoryItem “dirty” when changing some details of an element: you can implement the markDirty method in categoryItem , which looks like this:

 // CategoryItem.m -(void)markDirty { [self willChangeValueForKey:@"sequence"]; [self didChangeValueForKey:@"sequence"]; } // EditItemController.m item.attribute = newAttribute; for (CategoryItem *i in item.categoryItems) { [i markDirty]; } 
+2
source share

One-two relationships in Master Data: NSSet s, not NSOrderedSet s. For this reason, the index of the item in the category is not saved. You can add another entity to your underlying data model, for example, IndexValue . IndexValue will have two attributes: categoryId or categoryName (depending on what makes sense), and then categoryIndex . Item will then have a one-to-many relationship with this object (and from one to one the inverse relationship, since there is no need to reuse these entities, they must be unique). An IndexValue will be created for each Category that the Item is IndexValue .

EDIT: It seems that an ordered property has been added to support NSOrderedSet from one to many relationships in OS X 10.7 and iOS 5 . It should be what you aim and use. Documentation is permitted for this function, but the order must be maintained without using an NSSortDescriptor when receiving a link. Regarding reordering, I'm not sure how this is supported. Performance on large datasets is lower using this method, compared to the method described above, which I described.

+1
source share

All Articles