problem with between predicate - iphone

when using an nspredicate ( a between predicate) i had an exception.
there is the code i used:
NSMutableArray *returnedArray=[[[NSMutableArray alloc]init] autorelease];
NSManagedObjectContext *context = [self managedObjectContext];
NSEntityDescription *objEntity = [NSEntityDescription entityForName:#"Note" inManagedObjectContext:context];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:objEntity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"When" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
[sortDescriptor release];
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:
#"self.Reunion==%#",reunion];
NSNumber *endOfEtape=[NSNumber numberWithInt:[etape.positionDepart intValue]+[etape.duree intValue]];
NSExpression *s1 = [ NSExpression expressionForConstantValue: etape.positionDepart ];
NSExpression *s2 = [ NSExpression expressionForConstantValue: endOfEtape ];
NSArray *limits = [ NSArray arrayWithObjects: s1, s2, nil ];
NSPredicate *predicate2=[NSPredicate predicateWithFormat: #"self.When BETWEEN %#",limits];
NSPredicate *predicate=[NSCompoundPredicate andPredicateWithSubpredicates:
[NSArray arrayWithObjects:predicate1,predicate2,nil]];
[fetchRequest setPredicate:predicate];
NSArray *notes;
notes=[context executeFetchRequest:fetchRequest error:nil];
[fetchRequest release];
and i had an 'objc_exception_throw' at the line on which i call "executeFetchRequest:" method.
I will be happy if you can help me.
Thanks.

Unfortunately, the BETWEEN operand is considered an aggregate function & these aren't supported by CoreData.
See Apple's Documentation
... consider the BETWEEN operator (NSBetweenPredicateOperatorType); its
right hand side is a collection containing two elements. Using just
the Mac OS X v10.4 API, these elements must be constants, as there is
no way to populate them using variable expressions. On Mac OS X v10.4,
it is not possible to create a predicate template to the effect of
date between {$YESTERDAY, $TOMORROW}; instead you must create a new
predicate each time.
Aggregate expressions are not supported by Core Data.
So you'll need to use a predicate like:
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:
#"self.When >= %# AND self.When <= %#", etape.positionDepart, endOfEtape];
(assuming positionDepart and endOfEtape are of type NSString)

Related

How to sorting core data fetch result

hi i need to sort fetch result deasending order here is my code
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSError *error1;
NSEntityDescription *entityDesc;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
entityDesc=[NSEntityDescription entityForName:#"SubCategoryEntity" inManagedObjectContext:context];
[fetchRequest setEntity:entityDesc];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
initWithKey:#"subCategoryId" ascending:NO];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];
NSArray *array = [context executeFetchRequest:fetchRequest error:&error1];
here i use "subcategory" string type so it show me correct order in "single digits" but it couldn't work in "double digits"
here is i get order after count "11"
"9","8","7","6","5","4","3","2","1","10","0"
here i need to show "10","9","8","7","6","5","4","3","2","1","0"
i don't why it's happing can any one help me
Thanks for advance.
You're getting the order in this way because this is how sorting of strings work. You can try using NSSortDescriptor with custom compareSubCategoryId: selector in your custom SubCategory class for SubCategoryEntity.
update
Initialize your sort descriptor like this:
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"subCategoryId"
ascending:NO
selector:#selector(compareSubCategoryId:)];
Then add a method to your custom NSManagedObject subclass:
- (NSComparisonResult)compareSubCategoryId:(id)otherObject {
int ownSubCatId = [[self subCategoryId] intValue];
int otherSubCatId = [[otherObject subCategoryId] intValue];
if (ownSubCatId < otherSubCatId) return NSOrderedAscending;
if (ownSubCatId > otherSubCatId) return NSOrderedDescending;
return NSOrderedSame;
}

Filter NSFetchedResultsController to remove objects with same name

I have these objects that are unique except for two columns once of which I am using as the display in the UITableView. The UITableView will often show duplicates due to this. I need to filter out these duplicates somehow.
Setting distinctResult on the FetchResult won't work in this case since that limits the functionality of the NSFetchedResultsController and it requires that the REsultType be a NSDictionary instead of a subclass of managed object.
Doesn't anyone have any idea how I can filter these duplicates out using a predicate?? Remember that every field on these objects is unique except for two of them.
-(NSFetchedResultsController *) fetchGroupedObjects:(NSString *)entityDescription
sortField:(NSString *)sortField
withPredicate:(NSPredicate *)predicate {
BPRAppDelegate *delegate = (BPRAppDelegate *)[UIApplication sharedApplication].delegate;
NSManagedObjectContext *context = delegate.managedObjectContext;
//NSError *error;
//Fetch the data....
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:entityDescription inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSSortDescriptor *groupDescription = [[NSSortDescriptor alloc]
initWithKey:GROUP_NAME ascending:YES];
//Sort by Category Name
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
initWithKey:sortField ascending:YES];
NSMutableArray *sorts = [[[NSMutableArray alloc] init] autorelease];
[sorts addObject:sortDescriptor];
[sorts addObject:groupDescription];
[fetchRequest setSortDescriptors:sorts];
//[fetchRequest setResultType:NSDictionaryResultType];
//[fetchRequest setPropertiesToGroupBy:[entity.propertiesByName valueForKey:CONTRACTOR_NAME];
if (predicate != nil)
[fetchRequest setPredicate:predicate];
//NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
//NSFetchResultsController
[fetchRequest setFetchBatchSize:20];
NSFetchedResultsController *fetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:context sectionNameKeyPath:GROUP_NAME
cacheName:nil]; //Don't use a cache
[fetchRequest release];
[sortDescriptor release];
[groupDescription release];
return fetchedResultsController; //You can't autorelease this thing... the requestor must do that.
}
While it might be easier to set up an optional to-one relationship back to itself (say, "child") so that you can then fetch with a NSPredicate where "child == nil", you can certainly post-filter easily enough in pure objective C using [array enumerateObjectsUsingBlock:] or equivalent, and only add unique objects per your criteria to the resultant array.

Search NSFetchedResultsController using NSPredicate

I've been stuck on this problem for a while now and have tried my best to work out a solution.
I am using Core Data and, being relatively new to iOS coding, I'm having some trouble working out how to search my fetchedResultsController to filter out the string that the user types into the searchBar.
I know how to get the string from the searchBar and how to call my fetchResultsController method. But what I'm struggling with is how to use NSPredicate to match only the rows stored in using core data with that typed in the searchBar.
At the moment I'm doing this in - (NSFetchedResultsController *)fetchedResultsController
(I switch the sort alphabetically just to show myself that it's working).
if (!isSearching) {
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"LabelValue" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[sortDescriptor release];
[sortDescriptors release];
}
else {
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"LabelValue" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
NSLog(#"%#", searchBar.text);
/*NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ANY contains[cd] %#", searchBar.text];
[fetchRequest setPredicate:predicate];*/
[fetchRequest setSortDescriptors:sortDescriptors];
[sortDescriptor release];
[sortDescriptors release];
}
I don't quite understand how to use the predicate to filter my data. The commented out code causes an NSException when uncommented:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse the format string "ANY contains[cd] %#"'
It's probably quite a simple solution, but I'd be very grateful for any help you are able to offer. Thanks
   
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ANY <yourFieldNameHere> contains[cd] %#", searchBar.text];

NSPredicate - returning ever unique instance in a column

I was wondering if there was a predicate to return every unique instance in a column.
You can configure the NSFetchRequest to return uniques for you. Take a look at its documentation.
#distinctUnionOfArrays might work, depending on your situation: Core Data - Getting Unique Rows
Below is the code used to solve the problem.
- (NSMutableArray *)fetchNeighborhoods {
ProjectNameAppDelegate *appDelegate = (ProjectNameAppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *managedObjectContext = appDelegate.managedObjectContext;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Bar" inManagedObjectContext:managedObjectContext];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"neighborhood" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[fetchRequest setEntity:entity];
// Get array of results.
NSMutableArray *theResults = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
// Grab unique neighborhoods through NSSet.
NSSet *uniqueElements = [NSSet setWithArray:[theResults valueForKey:#"neighborhood"]];
// Dump NSSet uniques into new array.
NSMutableArray *sortedResults = [[NSMutableArray alloc] initWithArray:[uniqueElements allObjects]];
// Sort the results alphabetically.
sortedResults = [[sortedResults sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)] mutableCopy];
// Output unique results for verification.
for(int i = 0; i < [sortedResults count];i++){
NSLog(#"%d. %#", i+1, [sortedResults objectAtIndex:i]);
}
[sortDescriptor release];
[sortDescriptors release];
return sortedResults;
}

Core Data NSPredicate for relationships

My object graph is simple.
I've a feedentry object that stores info about RSS feeds and a relationship called Tag that links to "TagValues" object. Both the relation (to and inverse) are to-many. i.e, a feed can have multiple tags and a tag can be associated to multiple feeds.
I referred to How to do Core Data queries through a relationship? and created a NSFetchRequest. But when fetch data, I get an exception stating,
NSInvalidArgumentException
unimplemented SQL generation for predicate
What should I do? I'm a newbie to core data :( I know I've done something terribly wrong... Please help...
Thanks
--
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:#"FeedEntry" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"authorname" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSEntityDescription *tagEntity = [NSEntityDescription entityForName:#"TagValues" inManagedObjectContext:self.managedObjectContext];
NSPredicate *tagPredicate = [NSPredicate predicateWithFormat:#"tagName LIKE[c] 'nyt'"];
NSFetchRequest *tagRequest = [[NSFetchRequest alloc] init];
[tagRequest setEntity:tagEntity];
[tagRequest setPredicate:tagPredicate];
NSError *error = nil;
NSArray* predicates = [self.managedObjectContext executeFetchRequest:tagRequest error:&error];
TagValues *tv = (TagValues*) [predicates objectAtIndex:0];
NSLog(tv.tagName); // it is nyt here...
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"tag IN %#", predicates];
[fetchRequest setPredicate:predicate];
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:#"Root"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
--
The key here is "ANY"
Example from apple:
NSPredicate *predicate = [NSPredicate predicateWithFormat:
#"ANY employees.firstName like 'Matthew'"];
http://developer.apple.com/mac/library/documentation/cocoa/conceptual/CoreData/Articles/cdBindings.html
Do you require SQLite? I am grappling with a similar issue, and have found that everything works as expected with a binary store.
There are limitations when using SQLite as a store, though I have not yet found a document that lists the limitations, only that they exist.
Sorry I can't be of more help.