Search Through Core Data - iphone

All,
I have a core data entity, CreditCard, and each entity has four values.
So, what I need to do is search through ALL of my CreditCard entities and find the one with a property pocketNum that is equal to whatever value the user puts in, and then return it so I can pull necessary values from it.
How would I do this?
Thanks,
James

Try NSFetchRequest with NSPredicate:
// 'moc' is your NSManagedObjectContext instance
// 'yourPockerNum' is what you want to find
NSEntityDescription *entity = [NSEntityDescription entityForName:#"CreditCard" inManagedObjectContext:moc]
NSFetchRequest *request = [[NSFetchRequest alloc] init];
request.entity = entity;
request.resultType = NSDictionaryResultType;
request.predicate = [NSPredicate predicateWithFormat:#"pocketNum == %#", yourPocketNum];
NSError *error = nil;
NSArray *results = [moc executeFetchRequest:request error:&error];
// do something with results

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]];

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];

Need Help Setting Up Fetch Predicate

I am unsure as to what to use for the YourNameVariable. I think it needs to be an instance of Routine (or maybe the name property of Routine) but how do I create this? I am using a UITableView.
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Exercise" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
[request setPredicate: [NSPredicate predicateWithFormat: #"routineExercises = %#", yourVariableNameHere]];
NSLog(#"After managedObjectContext: %#", managedObjectContext);
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
// Handle the error.
}
[mutableFetchResults release];
[request release];
Here is my data model:
And also, should I be putting this in viewDidLoad or in the fetchResultsController's method?
You don't need a fetch if you already have the Routine objects. You just ask the Routine object for the contents of its routineExercises relationship.
You use fetches when you don't have an object to start with. If you already have an object, then you walk it's relationships to find it's associated objects. Fetching objects that are already in a relationship defeats the purpose of having relationships in the first place.

How to count in coredata (aggregation)?

I am learning core data and particularly working on aggregation.
Current what I want to do : count the number of records from the table which is in to-many relationship with inverse relationship on some criteria.
Currently I am doing this :
NSExpression *ex = [NSExpression expressionForFunction:#"count:"
arguments:[NSArray arrayWithObject:[NSExpression expressionForKeyPath:#"ddname"]]];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"ddtype == 'Home'"];
NSExpressionDescription *ed = [[NSExpressionDescription alloc] init];
[ed setName:#"countDDEvents"];
[ed setExpression:ex];
[ed setExpressionResultType:NSInteger16AttributeType];
NSArray *properties = [NSArray arrayWithObject:ed];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setPredicate:pred];
[request setPropertiesToFetch:properties];
[request setResultType:NSDictionaryResultType];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"DDEvent" inManagedObjectContext:[self.currentAccount managedObjectContext]];
[request setEntity:entity];
NSArray *results = [[self.currentAccount managedObjectContext] executeFetchRequest:request error:nil];
NSDictionary *dict = [results objectAtIndex:0];
NSLog(#"Average birthdate for female heroes: %#", [dict objectForKey:#"countDDEvents"]);
Its from jeff lemarche.
EDIT : and I have found my solution as
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"ddtype == 'Home'"];
[request setPredicate:pred];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"DDEvent" inManagedObjectContext:[self.currentAccount managedObjectContext]];
[request setEntity:entity];
NSError *error = nil;
NSUInteger count = [[self.currentAccount managedObjectContext] countForFetchRequest:request error:&error];
It is working nicely .But I want to do more request of such type at a time . So i think this can't be a preferred way of getting the count .
EDIT :
So I think the approach would be the appropriate one ????
So can anyone tell me more efficient an preferred way of doing this .
Thanks .
I had to count about 10 000 entities and it slowed down my interface responsiveness a lot while doing it with countForFetchRequest..
Here is a way of doing it wth NSExpression:
- (NSUInteger) unfilteredFCsCount {
// Just the fetchRequest
NSFetchRequest *fetchRequest = [self unfilteredFCsFetchRequest];
[fetchRequest setResultType: NSDictionaryResultType];
// You can use any attribute of the entity. its important, because you are not counting
// the properties, but actually the entities
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath: #"sortIndex_"]; // Does not really matter
NSExpression *maxExpression = [NSExpression expressionForFunction: #"count:"
arguments: [NSArray arrayWithObject:keyPathExpression]];
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
[expressionDescription setName: #"fcCount"];
[expressionDescription setExpression: maxExpression];
[expressionDescription setExpressionResultType: NSInteger32AttributeType];
[fetchRequest setPropertiesToFetch: [NSArray arrayWithObject:expressionDescription]];
NSUInteger fcCount = 0;
NSError *error = nil;
NSArray *results = nil;
results = [self.managedObjectContext executeFetchRequest: fetchRequest error: &error];
KSLog(KSLogLevelDebug, #"unfilteredFCsCount results: %#", results);
if([results count] > 0) {
NSNumber *count = [[results objectAtIndex: 0] objectForKey: #"fcCount"];
fcCount = [count intValue];
}
return fcCount;
}
Jeff LaMarche is just using this as a simple example. In practice, this need is so common that Key-Value Coding has a built in macro to handle it and other common collection operations.
See: The Key-Value Programming Guide: Set and Array Operators
In this case you would use the #count operator in your predicate.
Of course, hand tuning your own expression gives you fine control over your predicates but the operators handle 80% of such task.

Extract attributes from NSManagedObject array

NSFetchRequest *req = [NSFetchRequest init];
NSEntityDescription *descr = [NSEntityDescription entityForName:#"City" inManagedObjectContext:context];
[req setEntity:descr];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"streetName" ascending:YES];
[req setSortDescriptors:[NSArray arrayWithObject:sort]];
[sort release];
//fetch
NSError *error;
NSArray *result = [context executeFetchRequest:req error:&error];
//extract names
NSMutableArray *streets = [[NSMutableArray alloc] init];
for () {
??? = [array objectAtIndex:i];
[streets addObject:name];
}
I expected Core Data to be little more intuitive. I am new in it and I could use some help.
I fetched all objects(rows) from the entity (table) City. Now I have an array of objects. From the array I need to extract the attribute “streetName” to an array which will feed the picker. I figured I need to do it in the loop but I could not figure out the way to do it.
Please help.
I have a background with SQL but Core Data is still a big mystery to me. Is there any publication which would take a SQL statement and show comparable Core Data syntax?
Thanks.
It's very simple because of key-value coding:
NSArray *streets = [result valueForKey:#"streetName"];
i think core data changed quite a bit. here is how i do my fetch now
NSError *error;
NSFetchRequest *fr =[NSFetchRequest fetchRequestWithEntityName:#"Category"];
[fr setPredicate:[NSPredicate predicateWithFormat:#"name == \"myCategpry\""]];
NSArray *rs = [self.managedObjectContext executeFetchRequest:fr error:&error];
for (NSManagedObject *index in rs) {
NSLog(#"%#",[index primitiveValueForKey:#"name"]);
}