Fetch Data using predicate. Retrieve single value - iphone

I want to retrieve a single value (String) from "Entry." I believe I am missing something. Can someone point it out?
XYZAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *managedObjectContext = appDelegate.managedObjectContext;
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name == %#", entryToSearchFor];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Entry" inManagedObjectContext:managedObjectContext];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[request setEntity: entity];
[request setPredicate: predicate];
NSArray *results = [managedObjectContext executeFetchRequest:request error:nil];
if (results == nil) {
NSLog(#"No results found");
}else {
NSLog(#"entryToSearchFor %#", entryToSearchFor);
NSLog(#"results %#", [results objectAtIndex:0]);
}
Btw, the NSLog results outputs the following:
results <NSManagedObject: 0x3d2d360> (entity: Entry; id: 0x3d13650 <x-coredata://6EA12ADA-8C0B-477F-801C-B44FE6E6C91C/Entry/p3> ; data: <fault>)

NSFetchRequest will return an array of NSManagedObjects that matches the request. That is consistent with what you are seeing. Assuming you want to fetch the name, you can do NSLog(#"the name is %#", [[results objectAtIndex:0] name]); to print out the name.

Related

How to get the sm_owner User object using StackMob as backend

I find out the User has a sm_owner field. But how do I get the user using sm_owner. My code is like this:
[self.client getLoggedInUserOnSuccess:^(NSDictionary *result) {
NSString *currentLogginedUser = [result valueForKey:#"sm_owner"];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"User" inManagedObjectContext:self.managedOjbectContext];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"sm_owner like user/%#", currentLogginedUser];
[request setPredicate:predicate];
self.user = [[self.managedOjbectContext executeFetchRequest:request error:nil] objectAtIndex:0];
} onFailure:^(NSError *error) {
}];
And the crash message is:reason: 'Unimplemented SQL generation for predicate (sm_owner LIKE user / "user/test")'
I'm the platform Evangelist for StackMob.
The result from the getLoggedInUserOnSuccess method normally contains primary key "username". So the following code should work.
[self.client getLoggedInUserOnSuccess:^(NSDictionary *result) {
NSString *currentLogginedUser = [result objectForKey:#"username"];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"User" inManagedObjectContext:self.managedOjbectContext];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"username == %#", currentLogginedUser];
[request setPredicate:predicate];
self.user = [[self.managedOjbectContext executeFetchRequest:request error:nil] objectAtIndex:0];
} onFailure:^(NSError *error) {
}];
Alternatively, if you rather grab the sm_owner from the NSDictionary result. I would do the following.
NSString *sm_owner = [result valueForKey:#"sm_owner"];
NSArray *myArray = [sm_owner componentsSeparatedByString:#"/"];
NSString *currentLogginedUser = [myArray objectAtIndex:1];
Then perform your fetch.

How to sort a fetch in Core Data

I'm doing a fetch of data to show it in a UITableView, I do the fetch but I want to sort them by date of creation or by any sort method.
Here is the method:
-(NSArray *) lesStations {
NSManagedObjectContext *moc = [[AppDelegate sharedAppDelegate]managedObjectContext];
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Station" inManagedObjectContext:moc];
[fetch setEntity:entity];
NSError *error;
NSArray *result = [moc executeFetchRequest:fetch error:&error];
if (!result) {
return nil;
}
return result;
}
This should work
-(NSArray *) lesStations {
NSManagedObjectContext *moc = [[AppDelegate sharedAppDelegate]managedObjectContext];
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Station" inManagedObjectContext:moc];
[fetch setEntity:entity];
NSError *error;
NSArray *result = [moc executeFetchRequest:fetch error:&error];
if (!result) {
return nil;
}
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:"creationDate" ascending:YES];
NSArray *sortedResults = [result sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]];
[sort release];
return sortedResults;
}
You have 2 options: get the results sorted or sort the NSArray with the results:
NSFetchRequest could be set a NSArray of NSSortDescriptor
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"place" ascending:NO]; //the key is the attribute you want to sort by
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
You can also sort the returned NSArray (see all instance methods of NSArray starting with sortedArray...)
I suggest using the first approach when working with CoreData. The second one is just informative when working with arrays...
You can sort fetch results by setting sortDescriptors for fetch, e.g.
fetch.sortDescriptors = [NSArray arrayWithObjects:[[NSSortDescriptor alloc] initWithKey: ascending: selector:], nil];
NSError *error;
NSArray *result = [moc executeFetchRequest:fetch error:&error];

NSSortDescriptor to-many relationships

I use Core Data database.
I have Entity Album, that has many entities SpecificImage (key to get set of these images is #"specificImages")
I want to get Album with id = 1 and to sort attached SpecificImages by id.
I tried
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"specificImages.id" ascending:YES];
but I get the error
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: 'to-many key not allowed here'
Here is my code:
NSString *entityName = kEntityName;
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];;
NSManagedObjectContext *context = appDelegate.managedObjectContext;
NSEntityDescription *entityDesctiption = [NSEntityDescription
entityForName: entityName
inManagedObjectContext:context];
// find object
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"id == %d", CurrentCategoryItemID];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"specificImages.id" ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[request setEntity:entityDesctiption];
[request setPredicate:predicate];
NSArray *objects = [context executeFetchRequest:request error:nil];
[request release];
if (objects == nil)
{
NSLog(#"there was an error");
return;
}
else if ([objects count] == 0)
{
return;
}
NSManagedObject *object = [objects objectAtIndex:0];
it throws an exception, when I try to execute NSArray *objects = [context executeFetchRequest:request error:nil];
I am assuming, if you have many SpecificImages in Album then you will also have an inverse relationship from SpecificImage to Album ( 1 Album object in SpecificImage ).
Here I am first finding all SpecificImages for the required album id rather than all Albums and in the end form one of those SpecificImage object I will get the album object back.
NSString *entityName = #"SpecificImage";
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];;
NSManagedObjectContext *context = appDelegate.managedObjectContext;
NSEntityDescription *entityDesctiption = [NSEntityDescription
entityForName: entityName
inManagedObjectContext:context];
// find object
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"album.id == %d", CurrentCategoryItemID];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"id" ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[request setEntity:entityDesctiption];
[request setPredicate:predicate];
NSArray *specificImagesArray = [context executeFetchRequest:request error:nil];
[request release];
if (objects == nil)
{
NSLog(#"there was an error");
return;
}
else if ([objects count] == 0)
{
return;
}
Album *album = [(SpecificImage *)[specificImagesArray objectAtIndex:0] album];
The specificImagesArray is the array of specificImages you are looking for and album is your required album with id = CurrentCategoryItemID.
I think, there is no any variant, how to do this. I had this problem. But I had to sord it by id after executing fetch request.

iphone core data save not working

Im trying to save a list of Device classes (a custom class) using Core Data and retrieve it. But After I save it, my query, which is VERY simple, doesnt return any records.
My call to save the records always returns YES and no errors:
BOOL resultOfSave = [managedObjectContext save:&err];
My predicate for searching by the property userLogin is like so:
- (NSArray *) devicesForUser:(NSString *)username
{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Device" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"userLogin = %#", username];
[request setPredicate:predicate];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"macAddress" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];
NSError *error = nil;
NSArray *fetchResults = [managedObjectContext executeFetchRequest:request error:&error];
if (fetchResults == nil) {
// Handle the error.
NSLog(#"ERROR: nil fetch result array");
}
[request release];
NSLog(#"devicesForUser [%#] count %d", username, [fetchResults count]);
return fetchResults;
}
but I always get zero results, if I get rid of the predecate, I get all the objects, and if I loop through them I can see that the userLogin property for at least one of the object IS set to the username that I pass in...
Has anyone ever had an issue like this???
Thanks for any help you can give
Mark
In your predicate, change:
#"userLogin = %#"
...to:
#"userLogin == %#"

Core Data confusion: fetch without tableview

I have completed and reproduced Core Data tutorials using a tableview to display contents. However, I want to access an Entity through a fetch on a view without a tableview. I used the following fetch code, but the count returned is always 0. The data exists when the database is opened using SQLite tools.
NSManagedObject *entryObj;
XYZDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *managedObjectContext = appDelegate.managedObjectContext;
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Quote" inManagedObjectContext:managedObjectContext];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"id" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[request setEntity: entity];
NSArray *results = [managedObjectContext executeFetchRequest:request error:nil];
if (results == nil) {
NSLog(#"No results found");
entryObj = nil;
}else {
NSLog(#"results %d", [results count]);
}
[request release];
[sortDescriptors release];
count returned is always 0; it should be 5.
Can anyone point me to a reference or tutorial regarding creating a controller not to be used with a tableview.
As far as I can tell, everything looks fine (except I'm a little worried about using 'id' as an attribute name, since it's a keyword in Objective-C). Try removing the sort descriptor and see if that changes anything. Also, add an error check. Perhaps something is happening that that can tell you. And I assume "Quote" is the right name for the entity. If none of that helps, I don't think the problem is in the fetch request.
For what it's worth, here's how I would write it:
XYZDelegate * appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext * context = appDelegate.managedObjectContext;
NSFetchRequest * request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Quote" inManagedObjectContext:context];
NSSortDescriptor * sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"id" ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];
[request setEntity:[NSEntityDescription entityForName:#"Quote" inManagedObjectContext:context]];
NSError * error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];
[request release];
if (error) {
NSLog(#"ERROR: %# %#", [error localizedDescription], [error userInfo]);
}
if (results == nil) {
NSLog(#"No results found");
entryObj = nil;
}
else {
NSLog(#"results %d", [results count]);
}