How to select specific data in Core Data? - iphone

I have a sample program that use Core Data and load an sqlite database in it. And I am displaying all the values using this code
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Name"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (Name *name in fetchedObjects) {
NSLog(#"ID: %#", name.nameId);
NSLog(#"First Name: %#", name.first);
NSLog(#"Middle Name: %#", name.middle);
NSLog(#"Last Name: %#", name.last);
}
This code works fine, my problem here is that I can't select a specific data/record. Example I want to select the record with the ID = 1.
Thanks!

You have to use predicates (with NSPredicate) before your request execution.
Something like that :
NSPredicate *predicateID = [NSPredicate predicateWithFormat:#"nameID == %d",-1];
[fetchRequest setPredicate:predicateID];

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Name"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
//Add following method to your code. this will help you to get desired result.
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"yourColumnID == %#", yourID]];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (Name *name in fetchedObjects) {
NSLog(#"ID: %#", name.nameId);
NSLog(#"First Name: %#", name.first);
NSLog(#"Middle Name: %#", name.middle);
NSLog(#"Last Name: %#", name.last);
}

Related

NSFetchRequest not fetching chat messages in proper order

I am implementing a chat database using core data in iphone. I have created two entity chatuser and chatmessage. and there is one to many relationship between chatuser and chatmessgae entity. For one chatuser there can be many chatmessages. I am storing data like
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Chatuser"
inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"chatuser == %#", chatuser];
[request setPredicate:pred];
NSArray *userArray=[self.managedObjectContext executeFetchRequest:request error:&error];
if ([userArray count] > 0){
Chatuser *user = [userArray objectAtIndex:0];
Chatmessage *message = [NSEntityDescription insertNewObjectForEntityForName:#"Chatmessage" inManagedObjectContext:self.managedObjectContext];
message.chatmessage = chatmessage;
[user addAllchatmessagesObject:message];
NSError *error;
if(![self.managedObjectContext save:&error])
{
NSLog(#"whoops, couldn't save: %#", [error localizedDescription]);
}
}
// }
else
{
Chatuser *user = [NSEntityDescription insertNewObjectForEntityForName:#"Chatuser" inManagedObjectContext:self.managedObjectContext];
user.chatuser = chatUser;
Chatmessage *message = [NSEntityDescription insertNewObjectForEntityForName:#"Chatmessage" inManagedObjectContext:self.managedObjectContext];
message.chatmessage = chatmessage;
[user addAllchatmessagesObject:message];
NSError *error;
if(![self.managedObjectContext save:&error])
{
NSLog(#"whoops, couldn't save: %#", [error localizedDescription]);
}
}
and fetching data this way
managedObjectContext = appDelegate.managedObjectContext;
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"Chatuser" inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity];
NSError *error;
NSPredicate *pred = [NSPredicate predicateWithFormat:#"chatuser == %#", appDelegate.chatUser];
[request setPredicate:pred];
NSArray *userinfo = [self.managedObjectContext executeFetchRequest:request error:&error];
if([userinfo count]>0)
{
Chatuser *user = [userinfo objectAtIndex:0];
NSSet *messageset = user.allchatmessages;
self.messageinfo = [messageset allObjects];
int message_count=[self.messageinfo count];
NSLog(#"Message count : %d", message_count);
for(int i=(message_count-1);i>=0;i--)
{
Chatmessage *chatmsgnew = [self.messageinfo objectAtIndex:i];
[tableArray addObject:chatmsgnew.chatmessage];
}
}
now the problem is that chat messages is not coming in the order in which i am storing them. Like i am storing messages 1,2,3,4. and while fetching its coming like 2,1,4,3.....
I am not getting the problem. Can anybody suggest anything.
A fetch request does not necessarily return the objects in the order they were inserted into the database. If you need a specific order, you have to add an Integer attribute (e.g. messageId) to the entity, and add a sort descriptor to the fetch request:
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:#"messageId"
ascending:YES];
[request setSortDescriptors:#[sort]];
Added: The above method works if you fetch Chatmessage objects. So instead of fetching a Chatuser first, you could create a fetch request for the Chatmessage entity, with a predicate like
[NSPredicate predicateWithFormat:#"user.chatuser == %#", appDelegate.chatUser]
(assuming that "user" is the inverse relationship from Chatmessage to Chatuser), and the above sort descriptor.
Alternatively, if you have a Chatuser object, then you can sort user.allchatmessages like this:
NSSet *messageset = user.allchatmessages;
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:#"messageId"
ascending:YES];
self.messageinfo = [[messageset allObjects] sortedArrayUsingDescriptors:#[sort]];

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.

iPhone:similar to "where" type clause in core data

I am using core data first time in my application for my problem I have done google a lot but I didn't find specific solution.
I have Entity:SubCategory
Attributes:mainCategoryId,subCategoryName.
Now I want to fetch the data like
Select subCategoryName from SubCategory where mainCategoryId=1;
The code which I have implemented is as follows:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"SubCategory" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SubCategoryName == %#",#"Triangular1"];
[request setPredicate:predicate];
NSError *error;
arrSubCategory = [managedObjectContext executeFetchRequest:request error:&error];
How can I fetch similar kind of data in coredata
share your ideas
thanx in advance.
From your question what you need is,
[NSPredicate predicateWithFormat:#"mainCategoryId = %#",#"1"];
So your code will look like,
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"SubCategory" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *predicate =[NSPredicate predicateWithFormat:#"mainCategoryId = %#",#"1"];
[request setPredicate:predicate];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *info in fetchedObjects) {
NSLog(#"subCategoryName: %#", [info valueForKey:#"subCategoryName"]);
}
The above is just a sample code. Actual implementation could be different based on your requirement.
A tutorial on coredata is here. Check that out as well.
You can do it like this
NSString *maincategoryId = #"1";
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"SubCategory"];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"rubriqueid == %#", maincategoryId]];
and after you call your NSMutableArray to put your result:
NSMutableArray *answensmuarray = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];

How to fetch unique field values (song_type) from core data

I would like to know how to fetch unique field values (song_type) from core data.
i have the below code for that
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Songs" inManagedObjectContext:myManagedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:#"song_type"]];
[fetchRequest setEntity:entity];
NSError *aError;
NSMutableArray *fetchedResultsArray = [[myManagedObjectContext executeFetchRequest:fetchRequest error:&aError]mutableCopy];
if(! fetchedResultsArray ){
NSLog(#"EEEERRROR");
}
else {
NSLog(#"fetched %d", [fetchedResultsArray count]);
}
[fetchedResultsArray release];
[fetchRequest release];
i am getting the below error
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: 'Invalid keypath song_type
passed to setPropertiesToFetch:'
Set following 2 properties and you are done.
fetchRequest.returnsDistinctResults = YES;
fetchRequest.resultType = NSDictionaryResultType;
Hope this helps.
EDIT
NSFetchRequest *fetchRequest= [[NSFetchRequest alloc]init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Songs" inManagedObjectContext:myManagedObjectContext];
//Take properties dictionary
NSDictionary *entityProperties = [entity propertiesByName];
[fetchRequest setEntity:entity];
[fetchRequest setReturnsDistinctResults:YES];
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:[entityProperties objectForKey:#"song_type"]]];
NSArray * result = [myManagedObjectContext executeFetchRequest:fetchRequest error:nil];

Fetch Data using predicate. Retrieve single value

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.