I am trying to search in my application. There are two Core Data objects: "Tag" and "DvarTorah". The tag has only a string. "DvarTorah" has a title, text content and some other properties. I am trying to find the best way to quickly find them. The application has about 1200 DvarTorah objects and even more tags. Right now I am loading NSFetchedResultsController when my view view controller calls viewDidLoad. Then, when the user types in the search field or changes the scope, I call a method that takes both the value of the frame string and the search term and filters my array of objects. Here's what it looks like:
- (void) filterArrayWithSearchTerm:(NSString *)searchString andScopeIndex:(NSInteger)scopeIndex{
if ([searchString isEqualToString:@""]) {
return;
}
NSMutableArray *unfilteredResults = [[[[self.fetchedResultsController sections] objectAtIndex:0] objects] mutableCopy];
if (self.filteredArray == nil){
self.filteredArray = [[[NSMutableArray alloc ] init] autorelease];
}
[filteredArray removeAllObjects];
NSPredicate *predicate = [[[NSPredicate alloc] init] autorelease];
if (scopeIndex == 0) {
predicate = [NSPredicate predicateWithFormat:@"dvarTorahTitle CONTAINS[cd] %@", searchString];
}else if (scopeIndex == 1) {
predicate = [NSPredicate predicateWithFormat:@"searchableContent CONTAINS[cd] %@", [searchString canonicalString]];
}else if (scopeIndex == 2){
predicate = [NSPredicate predicateWithFormat:@"ANY tags.tagText CONTAINS[cd] %@", searchString];
}else{
predicate = [NSPredicate predicateWithFormat:@"(ANY tags.tagText CONTAINS[cd] %@) OR (dvarTorahTitle CONTAINS[cd] %@) OR (searchableContent CONTAINS[cd] %@)", searchString,searchString,searchString];
}
for (DvarTorah *dvarTorah in unfilteredResults) {
if ([predicate evaluateWithObject:dvarTorah]) {
[self.filteredArray addObject:dvarTorah];
}
}
[unfilteredResults release];
}
, . , CONTAINS , ( searchableContent) . ?
Edit:
, :
if ([searchString isEqualToString:@""]) {
return;
}
if (self.filteredArray == nil) {
self.filteredArray = [[[NSMutableArray alloc ] init] autorelease];
}
[filteredArray removeAllObjects];
NSPredicate *predicate = nil;
if (scopeIndex == 0) {
predicate = [NSPredicate predicateWithFormat:@"dvarTorahTitle CONTAINS[cd] %@", searchString];
}else if (scopeIndex == 1) {
predicate = [NSPredicate predicateWithFormat:@"searchableContent CONTAINS[cd] %@", [searchString canonicalString]];
}else if (scopeIndex == 2){
predicate = [NSPredicate predicateWithFormat:@"ANY tags.tagText CONTAINS[cd] %@", searchString];
}else{
predicate = [NSPredicate predicateWithFormat:@"(ANY tags.tagText CONTAINS[cd] %@) OR (dvarTorahTitle CONTAINS[cd] %@) OR (searchableContent CONTAINS[cd] %@)", searchString,searchString,searchString];
}
[self.filteredArray addObjectsFromArray:[[[[[self.fetchedResultsController sections] objectAtIndex:0] objects] mutableCopy] filteredArrayUsingPredicate:predicate]];
}
Edit2:
, :
- (void) filterArrayWithSearchTerm:(NSString *)searchString andScopeIndex:(NSInteger)scopeIndex{
if ([searchString isEqualToString:@""]) {
return;
}
if (self.filteredArray == nil) {
self.filteredArray = [[[NSMutableArray alloc ] init] autorelease];
}
[filteredArray removeAllObjects];
NSPredicate *predicate = nil;
if (scopeIndex == 0) {
predicate = [NSPredicate predicateWithFormat:@"dvarTorahTitle CONTAINS[cd] %@", searchString];
}else if (scopeIndex == 1) {
predicate = [NSPredicate predicateWithFormat:@"searchableContent CONTAINS[cd] %@", [searchString canonicalString]];
}else if (scopeIndex == 2){
predicate = [NSPredicate predicateWithFormat:@"ANY tags.tagText CONTAINS[cd] %@", searchString];
}else{
predicate = [NSPredicate predicateWithFormat:@"(ANY tags.tagText CONTAINS[cd] %@) OR (dvarTorahTitle CONTAINS[cd] %@) OR (searchableContent CONTAINS[cd] %@)", searchString,searchString,searchString];
}
[self.filteredArray addObjectsFromArray:[[[[self.fetchedResultsController sections] objectAtIndex:0] objects] filteredArrayUsingPredicate:predicate]];
}