I'm writing an application with Core Data that have to maintain a catalog with 4 levels of hierarchy.
Category <--->> SubCategory <--->> Item <--->> SubItem
I have a screen (table/collection view) where Items
are displayed along with Category
and SubCategory
titles. The Items could be. Basically I have to display filtered catalog. Let's say Item have a name and I want to filter items by name.
Example.
Category: Category 1
SubCategory: SubCategory 1.1
Items: [aaa, bbb, ccc, abc, abd, abg]
SubCategory: SubCategory 1.2
Items: [aaa, bbb, ccc]
Category: Category 2
SubCategory: SubCategory 2.1
Items: [123ab, 456ab, 123, 345, 456]
After filtering with query 'ab' I want to see the following objects:
Category: Category 1
SubCategory: SubCategory 1.1
Items: [abc, abd, abg]
Category: Category 2
SubCategory: SubCategory 2.1
Items: [123ab, 456ab]
The thing is: I can't use fetch request against Category
because it will only show me categories that contain items that satisfy criteria but it will not filter items. I can directly fetch filtered collection of Item
but I have to rebuild structure Category - SubCategory - Item
and put it in some arrays/dictionaries etc.
Is there a better way to filter deeply nested hierarchy with CoreData? The main question: is there a way to fetch leafs of deeply nested object tree while running fetch request against its root?
You can filter items
using searchString
by,
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]initWithEntityName:@"Item"];
NSPredicate *predicate = nil;
if([_searchBar.text length] > 0){
predicate = [NSPredicate predicateWithFormat:@"itemName CONTAINS[cd] %@", _searchBar.text];
}
if(predicate){
[fetchRequest setPredicate:predicate];
}
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]initWithKey:@"itemName" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
If you need to sort the result by considering category
and subCategory
, you can use more sort descriptors according to your priority like,
NSSortDescriptor *sortDescriptorCategory = [[NSSortDescriptor alloc]initWithKey:@"categoryName" ascending:YES];
NSSortDescriptor *sortDescriptorSubCategory = [[NSSortDescriptor alloc]initWithKey:@"subCategoryName" ascending:YES];
NSSortDescriptor *sortDescriptorItem = [[NSSortDescriptor alloc]initWithKey:@"itemName" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDescriptorCategory, sortDescriptorSubCategory, sortDescriptorItem, nil]];
You can just separate each key with a '.' like so...
NSSortDescriptor *sortDescriptorSubCategory = [[NSSortDescriptor alloc]initWithKey:@"Category.SubCategory.Items" ascending:YES];
then, in iOS 7 +
[YOUR_ARRAY sortedArrayUsingDescriptors:@[sortDescriptorSubCategory]];
Or, older iOS versions
[YOUR_ARRAY sortedArrayUsingDescriptors:[NSArray sortDescriptorSubCategory, nil]];
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.