nsset, core data, correct predicate - ios

I have "WorkoutList" object in CoreData, which contains field
#property (nullable, nonatomic, retain) NSSet<Workout *> *workoutList;
and have relationship one to many ("Workout" objects). Workout objects contain field named "finish", this is a string. I am trying to get an array of objects in which field "finish" and my string are equal.
NSEntityDescription* entity = [NSEntityDescription entityForName:#"WorkoutList" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity: entity];
if (dateString)
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"workoutList.finish == %#", dateString];
[fetchRequest setPredicate:predicate];
}
NSArray* fetchWorkoutList = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
But I can't write correct predicate for that. So my question is what is correct predicate in this example? Thanks in advance.

The correct predicate was #"ANY workoutList.finish == %#".

Related

using a predicate with fetch without a tableView

To learn about Core Data, I'm making a quiz app but it doesn't use a table view. I have the data for two quizzes seeded in the application. When a user clicks on a button on the view, I want to fetch a quiz, depending on which button he/she presses, but I'm not sure what I can put in for the predicate
if ([sender.currentTitle isEqualToString:#"sports"]){
NSError *error;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Quizdata"
inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"(SELF = %#)", ????]; ///unsure what to put here
[fetchRequest setPredicate:predicate];
self.fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
NSLog(#"fetched object %#", fetchedObjects);
}else if ([sender.currentTitle isEqualToString:#"entertainment"]){
NSLog(#"entertainment%#", sender.currentTitle);
}
I have two entities, for example Quiz.h, which I made classes for based on the attributes of the entities
#dynamic quizId;
#dynamic name;
#dynamic quizData;
and a QuizData.h entity
#dynamic answer1;
#dynamic answer2;
#dynamic answer3;
#dynamic answer4;
#dynamic correctAnswer;
#dynamic question;
#dynamic score;
#dynamic unique;
#dynamic quiz;
I had hoped to be able to fetch one of the two quizzes by doing something similar to what I'd do in Rails
Quizdata.where(quizId => 1)
Is it possible to only fetch the sports questions the way that I've done it (i.e. without using a table view). The reason why I thought tableView might be important is that it'll have object ids. I can't figure out how to get CoreData to retrieve every question for quizId 1.
I had previously imported data like this with json
{ "question" : "Do you like basketball", "answer1": "yes", "answer2": "no", "answer3": "maybe", "answer4":"of course", "correctAnswer": "yes", "unique": "2", "name": "sportsquiz", "quizId": "1"},
and then inserted and saved it with the two classes
Sure ...
I don't completely follow the logic on your Model As i'm not seeing a relationship between Quiz and QuizData.
If you had one, you would have an NSSet in Quiz containing a collection of QuizData. The you would simply perform an NSFetchRequest like this;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Quiz" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"quizId >= %#", [NSNumber numberWithInt:1]];
[fetchRequest setPredicate:predicate];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
FetchedObjects would contain an array of "Quiz" objects whose quizId >= 1. If you had set up your relationships correctly, each quiz object would contain a collection of quizData objects.
The main thing to remember is that Core Data is an Object Graph. As such, you would add quizData Objects to your Quiz object (as opposed to setting a relationship field and adding the relationship key to the Quiz object).

Integer Comparison through Predicate

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)

Validating data and looping through NSSet

I have a CoreData (SQLite) datamodel in xcode like so:
Friends Table
email
name
username
belongsToGroups
Groups Table
title
peopleInGroup
So the belongsToGroups and peopleInGroups is a many-to-many relationship with each other, both represented by NSSet in the code.
What do I use to query the NSSet for people in my groups and vice versa? (I'm new to CoreData)
With coredata, you can do it simple. Assume we have one object on Groups Table ( group), you want to get all friends belong to group, you can do:
[group. peopleInGroup allObjects]
For more detail:
Get group via title
NSError* error = nil;
NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] init];
NSPredicate *predicate;
NSEntityDescription *entity;
NSArray *fetchedObjects;
Group* group;
entity = [NSEntityDescription
entityForName:[NSString stringWithFormat:#"%#",[Group class]]
inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:#"(title like[c] \"%#\")" ,title]];
[fetchRequest setPredicate:predicate];
fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects.count > 0) {
group = [fetchedObjects lastObject];
}
return group;
}
Get all friend of group
NSMutableArray* friends = [NSMutableArray alloc] init];
[friends addObjectsFromArray:[group. peopleInGroup allObjects]];

Core data join table, has many through, fetched properties predicate

How do you write a Fetched Property for the Place Entity that will present an Array of Users?
For a fetched property users of Place that retrieves all users whose check-in is related to the given place, set
the destination of the fetched property to "User"
and the predicate to "ANY checkins.event == $FETCH_SOURCE"
Now you can get the array of users for a place:
Place *place = ...;
NSArray *users = [place valueForKey:#"users"];
This fetched property corresponds to the following fetch request:
Place *place = ...;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"User"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ANY checkins.event == %#", place];
[request setPredicate:predicate];
NSArray *users = [context executeFetchRequest:request error:&error];
If you declare the fetched property users as a dynamic property:
#interface Place (FetchedProperties)
#property(nonatomic, retain) NSArray *users;
#end
#implementation Place (FetchedProperties)
#dynamic users;
#end
then you can retrieve the value using property syntax:
NSArray *users = place.users;
// instead of: NSArray *users = [place valueForKey:#"users"];
But note that you can get the same result (as a set) directly, without using a fetched property:
Place *place = ...;
NSSet *users = [place.checkins valueForKey:#"user"];
I hope I did understand you correctly. You want a list of users that have checked in at a certain place?
Then you do it the other way around. You fetch all Users that have at least one Checkin with a certain Place.
In Core-Data terms you'll need a subquery for this.
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"User"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SUBQUERY(checkins, $CHECKIN, $CHECKIN.event == %#).#count > 0", place];
request.predicate = predicate;
/* and so on */
There is not much documentation about SUBQUERY. A little bit is written in the discussion of expressionForSubquery:usingIteratorVariable:predicate:.
And the fetched property would be in the Place entity with a destination entity User and the predicate SUBQUERY(checkins, $CHECKIN, $CHECKIN.event == $FETCH_SOURCE).#count > 0

Fetchrequest with NSPredicate not returning right values

I'm having a strange problem with Core Data.
The problem is that I'm looking for objects with a property less than X and it isn't returning all the values that matches.
There is no cache and I'm not using //[fetchRequest setFetchBatchSize:50];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"self.level <= [cd] %#", [self.filters objectForKey:#"level"]];
I add it to a MutableArray of predicates and later I execute
NSPredicate *myPredicate = [NSCompoundPredicate andPredicateWithSubpredicates: subPredicates];
This one it's in a function that returns myPredicate called preparePredicates. For the moment there aren't more predicates, only one.
It's NSLog returns: level <=[cd] "30".
I have tried it also with intValue of the string and %i
The main function:
NSError* error;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"myEntity"
inManagedObjectContext:self.context];
[fetchRequest setEntity:entity];
NSPredicate* predicate = [self preparePredicates];
[fetchRequest setPredicate:predicate];
//[fetchRequest setFetchBatchSize:50];
NSArray *fetchedObjects = [self.context executeFetchRequest:fetchRequest error:&error];
NSLog (#"Error: %#", error);
NSLog(#"los fetchedobjects: %i",[fetchedObjects count]);
return fetchedObjects;
It doesn't return any error.
If I look at the results there isn't one having a level of 6, but there are others that matches (all are less than the specified). I know there is one with level 6.
If I open the .sqlite in SQLite Database Browser, I can see it there.
If I do with this program a
SELECT * FROM zmyentity WHERE zlevel <30;
it doesn't appear, same as in Core Data do. But if I do a
SELECT * FROM zmyentity WHERE zlevel == 6;
it appears.
I really don't know what is happening. Maybe I'm making a rookie mistake, so please point me in the right direction.
Thank you very much in advance.
Probably you have stored the level as a String attribute, because
"30" < "6"
when comparing strings. Choosing a numeric attribute type (Integer 16/32/64) should solve the problem. The corresponding level property in the myEntity class has then the NSNumber type.
You should also omit the [cd] modifier in the predicate, because that enforces a string comparison.
You predicate could then look like this:
[NSPredicate predicateWithFormat:#"self.level <= %d", [[self.filters objectForKey:#"level"] intValue]]

Resources