Core Data iPhone - Loading a String - iphone

I am having troubles with understanding how to load data with Core Data. This is what I have:
Entity named 'People'
Attributes of this entity named 'firstName' (string), 'lastName' (string), 'isSpecial' (boolean), 'isVerySpecial' (boolean).
I want to get the first and last name of any person who is special or very special so that I can then put those names into labels and wherever I like as I wish. I have played about with fetch requests without luck.
Any help would be much appreciated, thanks.

Something like this should do it:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *weightEntity = [NSEntityDescription entityForName:#"Person" inManagedObjectContext:[[yourCoreDataManager sharedInstance] managedObjectContext]];
[fetchRequest setEntity:weightEntity];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"isSpecial == %# OR isVerySpecial == %#", [NSNumber numberWithBool:YES], [NSNumber numberWithBool:YES]]];
NSError *error = nil;
NSArray *result = [[yourCoreDataManager sharedInstance] managedObjectContext] executeFetchRequest:fetchRequest error:&error];
And then:
Person *person = [result objectAtIndex:0];
NSString *lastName = person.lastName;
NSString *firstName = person.firstName;

Something like that should do the trick:
self.fetchedResultsController = [Person fetchAllSortedBy:#"lastName" ascending:YES withPredicate:[NSPredicate predicateWithFormat:#"isSpecial == %# OR isVerySpecial == %#", [NSNumber numberWithBool:YES], [NSNumber numberWithBool:YES]] groupBy:nil delegate:self];
then you will get an array of persons in your fetchedResultsController. To get it simple use
NSMutableArray *yourArray = [NSMutableArray arrayWithArray: self.fetchedResultsController.fetchedObjects];
Hope it helps

Related

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.

Database update using Core Data

I am trying to update my local database when app gets response from the web server. When app gets the update from web server, I fetch the data from the local database by matching the id with the response and get one row and perform update code but local database does not get updated and also does not give an error.
What should be the solution???
-(void)checkID:(NSMutableDictionary *)dict
{
NSDictionary *dictEvent = [dict objectForKey:#"Event"];
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObject *selectedManagedObject = nil;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Events" inManagedObjectContext:context];
NSSortDescriptor *sortDescObj = [[NSSortDescriptor alloc] initWithKey:#"event_id" ascending:YES];
NSError *error = nil;
NSPredicate *predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:#"user_id=%# and event_id=%#",[NSNumber numberWithInt:[[dictEvent valueForKey:#"user_id"] intValue]],[NSNumber numberWithInt:[[dictEvent valueForKey:#"id"] intValue]]]];
NSLog(#"Predicate = %#",predicate);
NSArray *arrSortDescriptors = [NSArray arrayWithObject:sortDescObj];
[fetchRequest setSortDescriptors:arrSortDescriptors];
[fetchRequest setEntity:entity];
[fetchRequest setReturnsDistinctResults:YES];
[fetchRequest setPredicate:predicate];
NSArray *arrResult = [context executeFetchRequest:fetchRequest error:&error];
if ([arrResult count]>0)
{
NSArray *arrKey = [dictEvent allKeys];
NSArray *arrValue = [dictEvent allValues];
NSLog(#"ArrKey : %#\nArrValue : %#",arrKey,arrValue);
selectedManagedObject = [arrResult objectAtIndex:0];
for(int i = 0; i < [arrKey count] ; i++)
{
NSLog(#"selectedMng :- %#",selectedManagedObject);
NSLog(#"KEY: %#\t: %#",[arrKey objectAtIndex:i],[arrValue objectAtIndex:i]);
if ([[arrKey objectAtIndex:i]isEqualToString:#"id"])
{
[selectedManagedObject setValue:[arrValue objectAtIndex:i] forKey:#"event_id"];
}
else if([[arrKey objectAtIndex:i]isEqualToString:#"invited_status"])
{
[selectedManagedObject setValue:[arrValue objectAtIndex:i] forKey:#"invite_status"];
}
else
{
[selectedManagedObject setValue:[arrValue objectAtIndex:i] forKey:[arrKey objectAtIndex:i]];
}
}
if (! [selectedManagedObject.managedObjectContext save:&error])
{
NSLog(#"updateEntityIntoDataBaseNamed - Error :: %#", [error localizedDescription]);
}
// }
}
}
Besides modifying your predicate as suggested by #Martin
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"user_id=%# && event_id=%#",
[NSNumber numberWithInt:[[dictEvent valueForKey:#"user_id"] intValue]],
[NSNumber numberWithInt:[[dictEvent valueForKey:#"id"] intValue]]
];
note that in two cases, you are updating your object using non matching keys: this happens for id and event_id, and for invited_status and invite_status.
You cannot use stringWithFormat within predicateWithFormat. Your predicate should probably look like this:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"user_id=%# and event_id=%#",
[NSNumber numberWithInt:[[dictEvent valueForKey:#"user_id"] intValue]],
[NSNumber numberWithInt:[[dictEvent valueForKey:#"id"] intValue]]
];

Retrieve NSString from core-data error

The app needs to retrieve data from core-data then compare one of the values with an IF STATEMENT
MyAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSEntityDescription *getDetails = [NSEntityDescription entityForName:#"Detail" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:getDetails];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(genID = %i)", genID];
[request setPredicate:pred];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"genID" ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sort]];
NSError *error;
NSArray *objects = [context executeFetchRequest:request error:&error];
for (NSManagedObject *oneObject in objects) {
NSString *type = [oneObject valueForKey:#"type"];
if (type == #"straight") {
NSLog(#"straight");
//straight logic removed
}else if (type == #"Left") {
NSLog(#"Left");
//Left logic removed
}else {
NSLog(#"Else");
//Else logic removed
}
}
The issue is that it never goes into "straight" or "left" always the ELSE. Stepping through the code I can see that values do match straight and left, even dumped them into a log file shows them fine. What is wrong?
You need to compare strings using isEqual: or isEqualToString: or compare:.
For instance:
NSString *type = [oneObject valueForKey:#"type"];
if ([type isEqualToString:#"straight"])
// etc.
Search StackOverflow for "NSString equal" or "NSString compare" if you need more explanation. You aren't anywhere near the first person to ask this question, and you definitely won't be the last.

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.