NSPredicate returning all objects - ios

I'm trying to use the NSPredicate to only get specific objects. The problem is that all the objects are fetched and it should only be specific objects where the condition is correct.
- (void)fetchDevices {
// Fetch the devices from persistent data store
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Songs"];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Songs" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
// retrive the objects with a given value for a certain property
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"selectedRow == %#" , selectedRowNumber];
devices = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
[fetchRequest setPredicate:predicate];
}
The selectedRowNumber is an int declared in the .h file.
A look on my Songs entity:
PS. Please comment below if more information is required and i'll provide it.

You have to assign the predicate before executing the fetch request.
Also, if selectedRowNumber is an int then you have to use the %d format
instead of %#.
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"selectedRow == %d" , selectedRowNumber];
[fetchRequest setPredicate:predicate];
devices = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];

Try this,
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"selectedRow = %#" , [NSNumber numberWithInt: selectedRowNumber]];
[fetchRequest setPredicate:predicate];
devices = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];

there seems to be two problems.
I think you need to put [fetchRequest setPredicate:predicate]; before devices = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
Also #"selectedRow == %d" seems not right. You may want to change it to #"selectedRow = %d"
And no need to set entity again.
So the code may look like this.
- (void)fetchDevices {
int selectedRowNumber = 1;
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Songs"];
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"selectedRow = %d" , selectedRowNumber];
[fetchRequest setPredicate:predicate];
NSArray *devices = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
}
Let me know how it goes :)

There is no need of setting Entity using setEntity.
[fetchRequest setPredicate:predicate]
Just set predicate, it will work.
- (void)fetchDevices {
// Fetch the devices from persistent data store
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Songs"];
// retrive the objects with a given value for a certain property
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"selectedRow == %#" , selectedRowNumber];
[fetchRequest setPredicate:predicate];
devices = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
[fetchRequest setPredicate:predicate];
}

Related

Save the result of setPredicate to NSString

I have created NSPredicate to search the string in my coredata.
so in this case does anyone know how to save the result [fetchRequest setPredicate:predicate]; in NSString.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name CONTAINS[cd] %#",
mytext];
[fetchRequest setPredicate:predicate];
Write Your Table Name in #"YOUR_ENTITY_NAME"
Make sure that your table contains name column
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"YOUR_ENTITY_NAME"];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"name CONTAINS[cd] %#", mytext]];
NSMutableArray *arrResult = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
NSLog(#"%#", arrResult); //output
I think this will help you
NSArray *fetchedObjects;
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"your entity" inManagedObjectContext: context];
[fetch setEntity:entityDescription];
[fetch setPredicate:[NSPredicate predicateWithFormat:#"name CONTAINS[cd] %#", mytext]];
NSError * error = nil;
fetchedObjects = [context executeFetchRequest:fetch error:&error];
if([fetchedObjects count] == 1)
NSLog(#"%#",[fetchedObjects objectAtIndex:0]);

Unable to fetch specific column that from core data

I have created a an entity called Statutory with four columns namely name,complianceName,statMappingName,country
i want a get all complianceName names that matches a specific statMappingName. Following is my code
NSString *nameToGet = self.statNameArray[indexPath.row] ;
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"complianceName = %#", nameToGet];
[fetch setPredicate:predicate];
NSLog(#"n %#",predicate);
NSError *error = nil;
NSArray *results = [[self managedObjectContext] executeFetchRequest:fetch error:&error];
if(results) {
NSLog(#"Entities with that name: %#", results);
} else {
NSLog(#"Error: %#", error);
}
But it is not providing the compliance name specific to that statMappingName. How can I be able to get all complianceName that has a specific statMappingName?
Try this:-
NSString *firstName = statMappingName;
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"firstName == %#", firstName]];
If you want to fetch specific column from core data
You can use the below method:-
NSEntityDescription *entity = [NSEntityDescription entityForName:entityname inManagedObjectContext:self.managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setReturnsObjectsAsFaults:NO];
[request setEntity:entity];
[request setFetchLimit:1];
[request setPredicate:[NSPredicate predicateWithFormat:#"(complianceName LIKE %#)",nametoGet]];
NSError *error = nil;
NSMutableArray *tempDataArr = [[self.managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
Note:-
*entityname: Your entity name
*self.managedObjectContext : Your managedobjectcontext
To Get All compliance Name use the below method
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:entityName];
[fetchRequest setReturnsObjectsAsFaults:NO];
NSMutableArray *tempDataArr =[NSMutableArray new];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"(ANY complianceName LIKE %#)",nametoGet]];
tempDataArr = [[self.managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
try these code for contains statMappingName
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"complianceName contains[c] %#", statMappingName];

Is it possible to do case insensitive fetch in Core Data?

I am trying to execute a fetch request on NSManagedObjectContenxt and I want the predicate to be case insensitive.
I tried several solutions that I found but all of them works only on NSArray (filteredArrayUsingPredicate) but not on Core Data.
For example:
My persistent store contains an NSManagedObject, 'Car', with the attribute 'name' and its value is "GMC".
1) The following returns with an empty array:
NSFetchRequest* fetch = [[NSFetchRequest alloc] init];
fetch.entity = [NSEntityDescription entityForName:#"Car" inManagedObjectContext:moc];
fetch.predicate = [NSPredicate predicateWithFormat:#"name matches[c] %#", #"gmc"];
NSArray* cars = [moc executeFetchRequest:fetch error:nil];
2) The following crashes with 'EXC_BAD_ACCESS':
fetch.predicate = [NSPredicate predicateWithFormat:#"name ==[c] %#", #"gmc"];
NSArray* cars = [moc executeFetchRequest:fetch error:nil];
3) The only fetch that works is:
fetch.predicate = [NSPredicate predicateWithFormat:#"name == %#", #"GMC"];
NSArray* cars = [moc executeFetchRequest:fetch error:nil];
Is it possible to do case insensitive fetch in Core Data? And how?
Thanks.
Try below code:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"UPC ==[c] %# OR ItemID ==[c] %#", aUPCCode,aUPCCode];
The keywords "like" and "contains" seem to work just fine.
fetch.predicate = [NSPredicate predicateWithFormat:#"name like[c] %#", #"gmc"];
or
fetch.predicate = [NSPredicate predicateWithFormat:#"name contains[c] %#", #"gmc"];
More keyword options and details can be found here:
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html#//apple_ref/doc/uid/TP40001795-CJBDBHCB
and here
http://nshipster.com/nspredicate/
Use #selector(caseInsensitiveCompare:) with your fetchRequest like:
NSSortDescriptor *sortDescr = [NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES selector:#selector(caseInsensitiveCompare:)];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Car"];
[fetchRequest setSortDescriptors:#[sortDescr]];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"name matches[c] %#", #"gmc"]];
Then perform your fetch as usual.

NSFetchedResultsController with complicate predicate

I'm developing the app with UICollectionView.
It's collection of events arranged by date. I'm using NSFetchedResultsController to fetch data from DB. But I need to fetch current and future events + 2 past events.
For NSFetchRequest I'm using NSCompoundPredicate
NSPredicate *nextPredicate = [NSPredicate predicateWithFormat: #"startAt >= %#", [NSDate date]];
NSPredicate *previousPredicate = [NSPredicate predicateWithFormat:#"startAt < %#", [NSDate date]];
NSCompoundPredicate *resultPredicate = [NSCompoundPredicate andPredicateWithSubpredicates: #[nextPredicate, previuosPredicate]];
fetchRequest.predicate = resultPredicate;
And I have no idea how to limit previousPredicate to receive only 2 items.
If you know the date of current event than create a method that return date of the last event to fetch and then set the predicate on the main NSFetchRequest to that date.
-(NSDate *)dateOfPastEvent{
NSFetchRequest *request = [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"EntityName" inManagedObjectContext:_mainContext];
[request setEntity:entity];
NSSortDescriptor *sortDesc = [NSSortDescriptor sortDescriptorWithKey:#"startAt" ascending:NO];
[request setSortDescriptors:#[sortDesc]];
NSError *error = nil;
NSArray *array = [_mainContext executeFetchRequest:request error:&error];
__block NSDate *pastEventDate;
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){
if ([obj valueForKey:#"startAt"] == currentEventDate) {
if (array.count >= idx+2) {
pastEventDate = [[array objectAtIndex:idx+2] valueForKey:#"startAt"];
*stop = YES;
}
}
}];
return pastEventDate;
}
Now set the predicate for the above returned date
NSFetchRequest *requestForController = [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"EntityName" inManagedObjectContext:_mainContext];
[requestForController setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"startAt >= %#", [self dateOfPastEvent]];

NSFetchRequest using NSPredicate

I am trying to create a NSArray of all results of a filtered search through a core data database in this way:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"AllFiles" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *p1 = [NSPredicate predicateWithFormat:#"userID == %#", userID];
NSPredicate *p2 = [NSPredicate predicateWithFormat:#"folderNumber == %d", folderNumber];
NSPredicate *p3 = [NSPredicate predicateWithFormat:#"fileType == %#", type];
NSPredicate *fetchPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:#[p1, p2, p3]];
[fetchRequest setPredicate:fetchPredicate];
NSError *error;
NSArray* returnArray = [context executeFetchRequest:fetchRequest error:&error];
The files are created in this way:
AllFiles *newFile = [NSEntityDescription
insertNewObjectForEntityForName:#"AllFiles"
inManagedObjectContext:context];
newFile.userID = userID;
newFile.folderNumber = [NSString stringWithFormat:#"%d", folderNumber];
....
As you can see I am trying to filter the results given some of the parameters:
#"userID == %#", userID
However all results are returned, without filtering... Any ideas why?
You are using an OR predicate, at least one of those 3 is matching for all. I suspect [NSPredicate predicateWithFormat:#"fileType == %#", type] is gathering all your files
Try compositing an AND like so...
NSPredicate *idPredicate = [NSPredicate predicateWithFormat:#"userID == %#", userID];
NSPredicate *folderNumPredicate = [NSPredicate predicateWithFormat:#"folderNumber == %d", folderNumber];
NSPredicate *typePredicate = [NSPredicate predicateWithFormat:#"fileType == %#", type];
NSPredicate *fetchPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:#[idPredicate, folderNumPredicate, typePredicate];
[fetchRequest setPredicate:fetchPredicate];
Bear in mind that andPredicateWithSubpredicates and orPredicateWithSubpredicates return a NSPredicate so they can be composited together in complex ways if you need.

Resources