Get count of objects with specific relationship - iphone

I have to entity, A and B (A <<---> B) so an A object can have one B object and a B object can have more than one A object (Correct me if I'm wrong, I'm new to core data relationships).
Now, I want to know how many A objects are in a B object. For example I have a shop (employee <<---> shop) and I want to know how many employee work in that shop.
I've create something like this without success:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Task" inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"project == %#", aProject];
[request setPredicate:predicate];
NSError *error = nil;
NSInteger resultNumber = [self.managedObjectContext countForFetchRequest:request error:&error];
if (!resultNumber) {
NSLog(#"Risultati della richiesta nulli!");
abort();
}
NSLog(#"getCountOfProjects called");
NSLog(#"Results: %#", resultNumber);
return resultNumber;
Can you help me? Than you so much! ;)
Update
I've tried to use this code but it doesn't work...
-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
Project *projects = (Project *)[fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = projects.title;
cell.detailTextLabel.text = [NSString stringWithFormat:#"%# entries", [projects.task count]];
}

Why not just say something like [[myShop employees] count]?

Related

Update value core data

I need to update the value of the desired cell in my core data. I have a cell (ID) with a known value to me. I need to find the value and replace. I know how to change the elements of the array. The following shows how I do it. But I have to change the field (ID) in MyBase. value that I need to change will be equal to fromIndexPath.row. The value on which I need to change toIndexPath.row.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath
*)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
if (fromIndexPath.section == toIndexPath.section) {
NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription* entityDescription = [NSEntityDescription entityForName:#"MyBase"
inManagedObjectContext:self.objectContext];
[fetchRequest setEntity:entityDescription];
empArray = [(NSArray*)[self.objectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
MyBase *employee = [empArray objectAtIndex:fromIndexPath.row];
[empArray removeObjectAtIndex:fromIndexPath.row];
[empArray insertObject:objectToMove atIndex:toIndexPath.row];
}
}
for update core data, you can try this:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#:#"Employee"
inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity];
NSPredicate *pred = [NSPredicate predicateWithFormat:[NSString stringWithFormat:#"empId = %d", 12345]];
[request setPredicate:pred];
NSArray *empArray=[self.managedObjectContext executeFetchRequest:request error:nil];
[request release];
if ([empArray count] > 0){
Employee *employee = [empArray objectAtIndex:fromIndexPath.row];;
employee.empSalary=[NSNumber numberWithInt:45000];
employee.empName=#"John";
employee.empDesignation=#"Analysist";
employee.empExp=#"4 Years";
[self.managedObjectContext save:nil];

update an attribute using core data

I have an entity that has 3 attributes: firstname, lastname and score. i am able to search the score of a person by firstname and last name and display it on an UILabel (so far so good) my problem is that i don't know how to update the score attribute with a new value. below the code that i use to perform the search and display the old value.
NSEntityDescription *entitydesc = [NSEntityDescription entityForName:#"Scorecard" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
[request setEntity:entitydesc];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"firstname like %# and lastname like %#", self.firstnameTextField.text, self.lastnameTextField.text];
[request setPredicate:predicate];
NSError *error;
NSArray *integer = [context executeFetchRequest:request error:&error];
if(integer.count <= 0){
self.displayLabel.text = #"No records found";
}
else {
NSNumber *score;
for (NSManagedObject *object in integer) {
score = [object valueForKey:#"score"];
int x = [score intValue];
// New Value is going to be the old value + 2
int y = x + 2;
//displays old value found
[self.displayLabel setText:[NSString stringWithFormat:#"old value %d",x]];
}
}
update #1
i was able to update the attribute and save it however i had to convert my new Integer value to a string and then convert it back to an integer. i don't like the extra step. if anyone has another suggestion please let me know and thanks for the help. below the updated code.
NSEntityDescription *entitydesc = [NSEntityDescription entityForName:#"Scorecard" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
[request setEntity:entitydesc];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"firstname like %# and lastname like %#", self.firstnameTextField.text, self.lastnameTextField.text];
[request setPredicate:predicate];
NSError *error;
NSArray *integer = [context executeFetchRequest:request error:&error];
if(integer.count <= 0){
self.displayLabel.text = #"No records found";
}
else {
NSNumber *score;
for (NSManagedObject *object in integer) {
score = [object valueForKey:#"score"];
int x = [score intValue];
int y = x + 2;
NSString* z = [NSString stringWithFormat:#"%d",y];
[object setValue:[NSNumber numberWithInteger:[z integerValue]] forKey:#"score"];
[self.displayLabel setText:[NSString stringWithFormat:#"Value updated to %d",y]];
[context save:&error];
}
}
update 2
Thanks to Kevin's answer I was able to solve my problem. I am now able to replace an integer value from an attribute on my core data with another integer value. below my code finally working.
NSEntityDescription *entitydesc = [NSEntityDescription entityForName:#"Scorecard" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
[request setEntity:entitydesc];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"firstname like %# and lastname like %#", self.firstnameTextField.text, self.lastnameTextField.text];
[request setPredicate:predicate];
NSError *error;
NSArray *integer = [context executeFetchRequest:request error:&error];
if(integer.count <= 0){
self.displayLabel.text = #"No records found";
}
else {
NSNumber *score;
for (NSManagedObject *object in integer) {
score = [object valueForKey:#"score"];
int x = [score intValue];
int y = x + 2;
[object setValue:[NSNumber numberWithInt:y] forKey:#"score"];
[self.displayLabel setText:[NSString stringWithFormat:#"Value updated to %d",y]];
[context save:&error];
}
}
Get an object like you did before then set's it's score property
[object setValue:[NSNumber numberWithInt:y] forKey:#"score"];
My first suggestion would be to use NSManagedObject's subclasses instead of using primitives. You can do this by using the core data inspector and changing your entity class.
Now, to do a change to the score, you need to find the object you need to change, and assign the value. Once the value is assigned, you will need to save the NSManagedObject the object belongs to. Once the context successfully saves, your changes are persistent.

CoreData compare two NSManagedObjects by their attributes and relationships

I have filter object. It has several attributes and relationships. I want to create new filter object if there's no one with the same attributes & relationships. How to accomplish this ?
I would choose a more general approach..
I would take the NSEntityDescriptions of the object and build a predicate with all properties in that Description.
so like..
- (void)insertIfUnique:(NSManagedObject*)obj inContext:(NSManagedObjectContext*)ctx {
NSMutableString *format = [NSMutableString string];
NSEntityDescription *desc = obj.entity;
NSArray *attrs = desc.attributeKeys;
for(NSString *attr in attrs) {
if(format.length)
[format appendString:#" AND "];
[format appendFormat:#"%#==%#", attr, [obj valueForKey:attr]];
}
NSPredicate *p = [NSPredicate predicateWithFormat:format];
NSFetchRequest *f = [[NSFetchRequest alloc] initWithEntityName:desc.name];
f.predicate = p;
if([ctx countForFetchRequest:f error:nil]==0)
[ctx insertObject:obj];
}
You have to manually search CoreData for any existing filter objects. If not found, you can process to create a new filter:
Here is one helper function
+(id)uniqueEntityfForName:(NSString *)name
withValue:(id)value
forKey:(NSString *)key
inManagedObjectContext:(NSManagedObjectContext *)context {
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
request.entity = [NSEntityDescription entityForName:name inManagedObjectContext:context];
request.predicate = [NSPredicate predicateWithFormat:[key stringByAppendingString:#" == %#"], value];
NSArray *result = [context executeFetchRequest:request error:nil];
id entity = [result lastObject];
if (entity == nil) {
entity = [NSEntityDescription insertNewObjectForEntityForName:name inManagedObjectContext:context];
[entity setValue:value forKey:key];
} else {
entity = [result lastObject];
}
return entity;
}
I use this method like this:
SomeEntity *entity = [CDUtils uniqueEntityfForName:#"SomeEntity" withValue:#"foo" forKey:#"bar" inManagedObjectContext:context];
You may have to define your own predicate.

How To Get Name From NSArray

I have a NSFetchRequest to search of core data entities. It finds them fine, but I want to set the cell's text to the entity's name attribute.
I currently have this but I am setting the object itself to the title, instead of the name attribute, how can I fix this?
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Routine" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSError *error = nil;
NSArray *results = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
self.routineArray = results;
[fetchRequest release];
cell.textLabel.text = [self.routineArray objectAtIndex:indexPath.row];
Try :
cell.textLabel.text = [[self.routineArray objectAtIndex:indexPath.row] name];
EDIT
If your Routine instances are in routineArray (given that name, I suppose) :
// get the Routine instance
Routine *r = [self.routineArray objectAtIndex:indexPath.row];
// now you got your instance, set anything you want on r...
// ...
// and then set its name as the text for textLabel using previous instruction

Quick Question About Fetch And NSObject

I have the following code that fetches a Session object for a particular Exercise object.
This fetch loads data into my UITableView.
The count is fine, I just need a way to extract the Session.timeStamp property so I can set it to UITableViewCell's textLabel property.
Does anyone know how?
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"name == %#", exercise.name]];
NSEntityDescription *sessionEntity = [NSEntityDescription entityForName:#"Exercise" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:sessionEntity];
NSError *error = nil;
NSArray *results = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
NSMutableArray *mutableSessionArray = [NSMutableArray array];
for (Exercise *ex in results) {
Session *session = [ex exercises];
[mutableSessionArray addObject:session];
}
self.sessionArray = [NSArray arrayWithArray:mutableSessionArray];
Call timestamp property of your mananged object subclass or call valueForKey.