Integer Comparison through Predicate - ios

I am using core data in which I am having an entity called "Scan" who is having one attribute say electronic_id which is of NSNumber type. Now suppose in data base i am having 3 entries of this Scan attribute.
One entry of this entity having 35 as electronic_id.
Second entry of this entity having 354 as electronic_id.
Third entry of this entity having 375 as electronic_id.
I am performing searching on this attribute. so I when i start to search entity by passing 3 i want all these 3 objects.when i pass 35 then i want first two objects.
I want partial matches objects on NSNumber through predicate.
I am using this function.
-(void)filteredContentWithSearchText:(NSString*)searchText
{
if([searchText length])
{
int value=0;
value=[searchText intValue];
if ([strSelectedType isEqualToString:#"Electronic ID"])
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"electronic_id == %d",value];
NSManagedObjectContext *context =[self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Scan" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:predicate];
NSError *error=nil;
NSArray *results = [context executeFetchRequest:fetchRequest error:&error];
if (error==nil)
{
}
else if (error!=nil)
{
NSArray *results =[APP_DELEGATE CallForGetScan:YES Predicateis:predicate];
[arrSessionSearchData removeAllObjects];
[arrSessionSearchData addObjectsFromArray:results];
}
}
}
}
Please help how to compare integer in NSPredicate.
Thanks in Advance.

Try cast integer to string and compare it
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"electronic_id.stringValue CONTAINS[c] %#",searchText];

#sage444 your answer is what I have looking for hours. Works like a charm.
I just provide Swift version for future readers:
let predicate = NSPredicate(format: "%K.stringValue CONTAINS[c] %#",
#keyPath(YOUR_MODEL.number),
substring)

Related

NSPredicate to check property of first 5 objects in a Core Data Relationship

I am looking to create a predicate that can check the TypeID of the first 5 objects in a Core Data relationship.
Here is what I am trying, but it doesn't work:
int num = 5;
NSMutableArray *predicates = [[NSMutableArray alloc] init];
for (int i = 0; i < num; i++) {
[predicates addObject:[NSPredicate predicateWithFormat:#"SELF IN %# AND logs[%i].TypeID == 3", items, i]];
}
This gives the error:
error: SQLCore dispatchRequest: exception handling request:
< NSSQLFetchRequestContext: 0x281837aa0 > , Unsupported function
expression logs[0].TypeID with userInfo of (null) CoreData:
error: SQLCore dispatchRequest: exception handling request:
< NSSQLFetchRequestContext: 0x281837aa0 > , Unsupported function
expression logs[0].TypeID with userInfo of (null)
I realize I am probably doing this wrong, so is there a different way that I could be doing this using NSPredicate?
if you want only fetch 5. Set fetchLimit to 5. Maybe the following code can not run right away, but the principle is same. You can add a property or get function to assign the "logs.TypeID" like -(Int)myID {return logs[0].TypeID;} then "SELF IN %# AND myID == 3" would solve the problem.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Entity name" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF IN %# AND logs.TypeID == 3", items];
[fetchRequest setPredicate:predicate];
fetchRequest.fetchLimit = 5;
NSError *error = nil;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
}
I’m not sure I understand the questions, but I don’t think it’s possible to do what you asked, at least not as worded. It doesn’t seem like it would be possible to inspect only five objects in the relationship and stop there, returning any number of matches or none at all, even if there are more in the database.
However, and I think this may be what you were getting at, it is possible to find five objects that are both in the items set and have at least one log with a typeID == 3. It can be done similar to what E.Coms proposed, except you need a subquery to handle the relationship. (I am assuming logs is a to-many relationship, either one-to-many or many-to-many).
Note that the following code has not been tested:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Entity name" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF IN %# AND SUBQUERY(logs, $log, $log.typeID == 3).#count != 0", items];
[fetchRequest setPredicate:predicate];
fetchRequest.fetchLimit = 5;
NSError *error = nil;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
}

NSPredicate weird crash with NSString

I'm trying to get a CoreData entity based on her name, to do that a created a method, that accepts a name parameter (NSString), so this is the method:
-(void)pegarCategoryByName:(NSString *)catName {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
NSLog(#"Category Name: %#", catName);
NSError *error = nil;
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Categorias" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"categoria == '%#'", catName];
[fetchRequest setPredicate:predicate];
// [fetchRequest setFetchLimit:1];
NSArray *fetchedObjects = [[self managedObjectContext]executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects.count > 0) {
_categoriaAtual = [fetchedObjects objectAtIndex:0];
} else {
NSLog(#"Category not Found");
}
}
So lets say i call somewhere in my code:
[self pegarCategoryByName:#"Songs"];
When i run i get the NSLog: Category Name Songs, Category not Found and them the App crashes.
The weird part is, if i change the NSPredicate on pegarCategoryName to not use the NSString passed, here's and example:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"categoria == 'Songs'"];
Everything works just fine.
Do not enclose the %# placeholder in the predicate format in quotation marks:
[NSPredicate predicateWithFormat:#"categoria == %#", catName];
catName is already a string; you don't need to surround it with quotes, it would be the same as:
categoria == '#"Songs"'
so remove them:
#"categoria == %#"

Fetch objects from an entity of one to many relationship core data

I was scratching my head all the way through to get this problem solved my self but unfortunately i couldn't.
So my problem is i have multiple values corresponding to one lectures so i made lectureTpPbl,lectureToProfessor,lecturetoStudyProgram relation of type one to many relationship as shown in image.
i saved into the DB like below:
-(void)saveToDatabase:(NSMutableDictionary *)inData{
LectureDetails *lectureDetail = (LectureDetails *)[NSEntityDescription insertNewObjectForEntityForName:#"LectureDetails" inManagedObjectContext:context];
[lectureDetail setAverageRating:[inData valueForKey:kLectureAverageRating]];
[lectureDetail setCategoryID:[inData valueForKey:kLectureCategoryID]];
[lectureDetail setCategoryName:[inData valueForKey:kLectureCategoryName]];
[lectureDetail setLectureID:[inData valueForKey:kLectureID]];
[lectureDetail setSemesterID:[inData valueForKey:#"SemesterID"]];
[lectureDetail setStartTime:[inData valueForKey:kLectureStartTime]];
[lectureDetail setRatingType:[inData valueForKey:kRatingType]];
[lectureDetail setMonth:[NSNumber numberWithInt:[[[[inData valueForKey:kLectureDate] componentsSeparatedByString:#"-"] objectAtIndex:1] integerValue]]];
[lectureDetail setDateOnly:[NSNumber numberWithInt:[[[[inData valueForKey:kLectureDate] componentsSeparatedByString:#"-"] objectAtIndex:2] integerValue]]];
for (id prof in [inData valueForKey:#"Professors"]) {
ProfessorsInLecture *profData = (ProfessorsInLecture *)[NSEntityDescription insertNewObjectForEntityForName:#"ProfessorsInLecture" inManagedObjectContext:context];
profData.professorID=[NSNumber numberWithInt:[[prof valueForKey:#"ProfessorID"]integerValue]] ;
profData.professorFirstName=[prof valueForKey:#"ProfessorFirstName"];
profData.professorLastName=[prof valueForKey:#"ProfessorLastName"];
profData.ProfessorUserName=[prof valueForKey:#"ProfessorUserName"];
[lectureDetail addLectureToProfessorObject:profData];
}
for (id prog in [inData valueForKey:#"StudyPrograms"]) {
StudyProgramInLecture *stdyProgramData = (StudyProgramInLecture *)[NSEntityDescription insertNewObjectForEntityForName:#"StudyProgramInLecture" inManagedObjectContext:context];
stdyProgramData.sMID=[prog valueForKey:#"SMID"];
[lectureDetail addLectureToStudyProgramObject:stdyProgramData];
}
for (id pblData in [inData valueForKey:#"PBLs"]) {
PBLinLectures *pbl = (PBLinLectures *)[NSEntityDescription insertNewObjectForEntityForName:#"PBLinLectures" inManagedObjectContext:context];
[pbl setLecturePBLID:[pblData valueForKey:#"LecturePBLID"]];
[pbl setPBLID:[pblData valueForKey:#"PBLID"]];
[lectureDetail addLectureToPBLObject:pbl];
}
NSError *error1;
if (![context save:&error1])
{
//NSLog(#"ERROR--%#",error);
abort();
}
}
all the data is getting save correctly but i am getting problem in fetching the data.
Now suppose i have to fetch a lecture whose semesterID=7 and month=12 and day=20 and (in relation table)sMID=2 and (in relation table)pBLID=4.
what i have done so far is to fetch is
-(NSMutableArray *)fetchDataforMonth:(NSNumber *)month andDate:(NSNumber *)dateOnly
{
NSEntityDescription *entity = [NSEntityDescription entityForName:#"LectureDetails" inManagedObjectContext:context];
// Setup the fetch request
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ANY lectureToPBL.pBLID ==%#", [NSNumber numberWithInt:[[[UserDetail sharedInstance].userDetail valueForKey:#"pBLID"]integerValue]]];
NSPredicate *pred1 =
[NSPredicate predicateWithFormat:#"(dateOnly == %#)",dateOnly];
NSPredicate *pred2 =
[NSPredicate predicateWithFormat:#"(month == %#)",month];
NSPredicate *pred3 =
[NSPredicate predicateWithFormat:#"(semesterID == %#)",[NSNumber numberWithInt:[[[UserDetail sharedInstance].userDetail valueForKey:#"semesterID"]integerValue]]];
NSPredicate *pred4 = [NSPredicate predicateWithFormat:#"ANY lectureToStudyProgram.sMID ==%#", [NSNumber numberWithInt:[[[UserDetail sharedInstance].userDetail valueForKey:#"programID"]integerValue]]];
NSArray *compPredicatesList = [NSArray arrayWithObjects:pred1,pred2,pred3,predicate,pred4, nil];
NSPredicate *CompPrediWithAnd = [NSCompoundPredicate andPredicateWithSubpredicates:compPredicatesList];
[request setPredicate: CompPrediWithAnd];
// Fetch the records and handle an error
NSError *error;
NSMutableArray *mutableFetchResults = [[context executeFetchRequest:request error:&error] mutableCopy];
return mutableFetchResults;
}
If there is one sMID and one pBLID then fetching is working fine otherwise i am not getting an object in fetch result.
Suppose i have a lecture whose semesterID is 7 and month=12 and day=20 and have multiples sMID such as 1,2,3 and multiples pBLID such as =4,5,6
and i want to fetch a lecture whose month=12 and day=20 and sMID=2 and pBLID=4
Can anybody tell me how to do that?
Any Help will be appreciated.
Thanks
First filter the Lecturers whose month=12 and day=20 from LectureDetails entity:
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(month == %#) AND (dateOnly == %#) ",month, dateOnly];
[request setPredicate: pred];
NSError *error;
NSArray *lectureList = [context executeFetchRequest:request error:&error];
then filter this array with pBLID and sMID.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(ANY lectureToStudyProgram.sMID ==%#) AND (ANY lectureToStudyPBL.pBLID ==%#)", sMID, pBLID];
lectureList = [lectureList filteredArrayUsingPredicate:predicate];
Now lectureList will give you the result.

Core Data NSFetchrequest integer

I have the following scenario. I have an app that handles data by using Core Data. I have an entity called "Brothers" which has 3 attributes: Name, Status, Age.
lets say that I have 1 record on my database that has:
-Name ==> Joe (String)
-Status ==> Married (String)
-Age ==> 28 (Integer)
I have an UIlabel a UItextfield and a Button. I want to be able to type the name (in this case Joe) on the UItextfield press the button and display the age (in this case 28) in the UILabel. I would also like to store the age value into a variable type integer so I can make some calculations with it later on.
below the code that I have inside the button.
NSEntityDescription *entitydesc = [NSEntityDescription entityForName:#"Brothers" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
[request setEntity:entitydesc];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"age %d", [self.age.text integerValue]];
[request setPredicate:predicate];
NSError *error;
NSArray *integer = [context executeFetchRequest:request error:&error];
self.displayLabel.text = integer;
Update #1
I updated the code that i have inside the button and now i am able to search by the name and display the age. I'm still looking into storing the age as an integer into a variable so i can use it later on.
NSEntityDescription *entitydesc = [NSEntityDescription entityForName:#"Brothers" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
[request setEntity:entitydesc];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"firstname like %#", self.firstnameTextField.text];
[request setPredicate:predicate];
NSError *error;
NSArray *integer = [context executeFetchRequest:request error:&error];
if(integer.count <= 0){
self.displayLabel.text = #"No records found";
}
else {
NSString *age;
for (NSManagedObject *object in integer) {
age = [object valueForKey:#"age"];
}
self.displayLabel.text = [NSString stringWithFormat:#"age: %#",age];
}
}
A predicate is an expression. If the expression evaluates to true then the predicate is satisfied. So if you were searching by age you'd use e.g.
[NSPredicate predicateWithFormat:#"age = %d", [self.age.text integerValue]]
Or by name:
[NSPredicate predicateWithFormat:#"name = %#", someNameOrOther]
Or by both:
[NSPredicate predicateWithFormat:#"(name = %#) and (age = %d)", someNameOrOther, [self.age.text integerValue]]
A fetch request gets the actual NSManagedObjects. So you'd get back an array of Brothers. Therefore you probably want something more like this to output a name:
if([array count])
self.displayLabel.text = [array[0] name];
Or for an age:
...
self.displayLabel.text = [[array[0] age] stringValue];
Or whatever other property you're outputting.
I think your predicate is wrong, the proper format would be this:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"age.integerValue == %d", [self.age.text integerValue]];

Core Data: deleteObject crashes application, NSPredicate the cause?

I'm using a UICollectionView along with Core Data.
I can't seem to figure out why I can't remove an object from Core Data. It crashes at [self.managedObjectContext deleteObject:animation]; with an index 0 beyond bounds for empty array error. The following method is a delegate method that gets invoked from another viewcontroller. It gets a timestamp NSInteger and should create an NSPredicate with that timestamp.
The strange thing is that when I take the animationTimestamp NSInteger and hardcode it like:
[NSPredicate predicateWithFormat:#"timestamp == %i", #"1370169109"] it works and the object gets deleted without the error. However, when I want to pass the parameter as the argument it crashes. I've tried making it a string, NSNumber etc. Nothing works when I take the parameter, it only does when I hardcode it. I've logged animationTimestamp and it shows the correct value, so I'm stuck.
Thanks!
- (void)deleteAnimationWithTimestamp:(NSInteger)animationTimestamp {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Animations" inManagedObjectContext:self.managedObjectContext];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"timestamp == %i", animationTimestamp];
[fetchRequest setPredicate:predicate];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *animations = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *animation in animations) {
[self.managedObjectContext deleteObject:animation];
}
// Save core data
if (![self.managedObjectContext save:&error]) {
NSLog(#"Couldn't save: %#", [error localizedDescription]);
}
[self.animationsCollectionView reloadData];
}
EDIT:
More info that might matter. The timestamp attribute in the model is a 64 bit integer (should it be by the way?). When I create the object I use:
NSNumber *timestampNumber = [NSNumber numberWithInt:timestamp];
[newAnimation setValue:timestampNumber forKey:#"timestamp"];
Get the NSInteger value from NSNumber
Like
NSInteger timestampNumber = [[NSNumber numberWithInt:timestamp] integerValue];
// then use this integer
[newAnimation setValue:timestampNumber forKey:#"timestamp"];
// or in
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"timestamp == %d", timestampNumber];

Resources