Error while fetching data from Core Data - objective-c

I’m working on an dictionary app. this app using core data and I'm very new to core data. In the database, records stored with a single entity called dictionary and dictionary entity has just two attributes “English” & “Meaning”.
So whenever user types some char say a, in UISearchBar, I want to fetch records from data base that starts from “a”, if user types data a than b that I want to fetch records starts from “ab” and so on.
I’m trying same thing by below code:
// Fetch the devices from persistent data store
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:ENTITY_NAME inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
// retrive the objects with a given value for a certain property
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K beginswith[c] %#",#"English",searchText];
[request setPredicate:predicate];
// Edit the sort key as appropriate.
/*NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"English" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];*/
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
/*NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:#"Root"];
aFetchedResultsController.delegate = self;*/
NSError *error = nil;
_searchResult = [managedObjectContext executeFetchRequest:request error:&error];
when this code executes my app crashes with the following error msg:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'keypath English not found in entity <NSSQLEntity TamilEnglishDict id=1>'
EDIT:
this is how my Data Model is...
Any who can guide me to the right path of fetching records properly?

Yes it's case sensitive.
So the correct predicate is the following.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K beginswith[c] %#",#"english", searchText];
or just
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"english beginswith[c] %#", searchText];
but while saving those values in managedObject I wrote '[managedObject
setValue:[obj objectForKey:#"English"] forKey:#"English"]';
So now edit your question and explain me the comment above. What do you mean?
Maybe you could just do
[managedObject setValue:[obj objectForKey:#"English"] forKey:#"english"];

I saw your code & your code is correct, you just have to change Predicate you are using. just replace this code with your predicate & hope your problem is solve. because you want result that conatain "ab" or "a" or "b" so you have to use "contain" in place of "beginswith".
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"%K contains[cd] %#",#"English", searchText];
Let me know if you have any issue.

Related

Core Data and NSPredicate

I'm looking for a way to use NSPredicate to set a "beginswith [cp]" condition to fetch objects. In the data model there is an one entity which contains 4 basic attributes. Name of first attribute is cityName. The goal is to find records for which cityName begins with given character, but I'm not sure how to format the predicate.
This is part of my code for this
NSString * lastCharacter = [userCity substringFromIndex:[userCity length] -1];
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context =
[appDelegate managedObjectContext];
NSEntityDescription *entityDesc =
[NSEntityDescription entityForName:#"Cities"
inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(cityName = beginswith [cp] %# )", lastCharacter];
[request setPredicate:pred];
but for this code I get following error:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse the format string "(cityName = beginswith [cp] %# )"'
The problem is that the beginswith is an operator, so = beginswith is one too much. The brackets in your predicate are also not necessary. Thus:
[NSPredicate predicateWithFormat:#"cityName beginswith[cd] %#", lastCharacter];
Just change your predicate like this :-
NSPredicate *pred = [NSPredicate predicateWithFormat:#"cityName contains[cd] %#",lastCharacter];

NSPredicate creation with CoreData for an equal object

I have a strong pointer with the name "sensor" to an object of the class "SensorDB".
I tried to create a NSFetchedResultController so that my UIViewController gets notified, if something changes inside the "sensor" object.
To get the desired object into my NSFetchedResultController, I created following NSPredicate:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"self == %#", self.sensor];
The goal is, that I have just one object in the NSFetchedResultController and get notifications about any updates, so that I can update my GUI.
But if I run my application, the app crashes when I try to alloc and init the NSFetchedResultController.
Here's my NSFetchedResultController code:
- (NSFetchedResultsController *)fetchedResultsControllerSensor
{
if (_fetchedResultsControllerSensor != nil) {
return _fetchedResultsControllerSensor;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"SensorDB" inManagedObjectContext:dbHandler.managedObjectContext];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"self == %#", self.sensor];
[fetchRequest setPredicate:predicate];
[fetchRequest setFetchBatchSize:20];
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:dbHandler.managedObjectContext sectionNameKeyPath:nil cacheName:#"SensorCache"];
self.fetchedResultsControllerSensor = theFetchedResultsController;
_fetchedResultsControllerSensor.delegate = self;
return _fetchedResultsControllerSensor;
}
Thank you for your help or another/better approach
Linard
I thought, that I don't need a sort descriptor, because I've just one result object, but it looks like that the initialization of a NSFetchedResultController crashes, if there isn't at least one NSSortDescriptor.
That's now my NSPredicate and NSSortDescriptor:
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"(SELF = %#)", self.sensor];
[fetchRequest setPredicate:predicate];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"displayOrder" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];

NSPredicate count number of NSString

I have a Event Entity with a action as Attribute. The action is a NSString that gets saved to core data on each event in my iOS app. The event.action will always be a predefined string e.g.. "Work" "Home" "Lunch"
How can I use NSPredicate to retrieve the last 5 actions and give me the action that was performed the most?
Are there any good tutorials on using NSPredicate?
Could you please try the following, hope at lease guide you :)
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Event"
inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF IN %#", #[#"Work", #"Home", #"Lunch"]]; //contain your actions
[request setPredicate:predicate];
request.fetchLimit = 5;// retrieve the last 5 actions
NSError *error;
NSArray *yourActions = [managedObjectContext executeFetchRequest:request error:&error];
for (Event *event in yourActions)
{
// find the action that was perform the most in last 5 actions
}
please give me a feedback, so I know what's happen, so I can edit the code to help you :).
thanks for the following references:
Using Core Data with NSPredicate and NSDate
Dynamically setting fetchLimit for NSFetchedResultsController
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Predicates/Articles/pUsing.html#//apple_ref/doc/uid/TP40001794-CJBDBHCB

Using an NSPredicate to access self.items

For various reasons (summarized at the end) I am experimenting with using an NSFetchedResultsController to return some NSManagedObjects.
Specifically, a Person has many Cars, modeled using the core data relationship cars. I want to add another method to Person to return the same cars as self.cars, but using a FRC.
I think I am making a basic error with my NSPredicate, which is designed to only find the cars where car.person == self:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Car"];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"dateAdded" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"person == '%#'", self];
[fetchRequest setPredicate:predicate];
NSFetchedResultsController *controller = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil
cacheName:nil];
NSError *error;
BOOL success = [controller performFetch:&error];
No cars are being returned at all. Is my predicate incorrect?
Side Note - why not just use self.cars?
Like I say this is an experiment. I am hoping to benefit from the persistent cache of an NSFetchedResultsController.
The single quotes in the predicate are wrong, it should be
[NSPredicate predicateWithFormat:#"person == %#", self];
In the example you are fetching "Person" objects. Maybe you want to fetch "Car" objects instead?
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Car"];

How to do Core Data queries through a relationship?

I'm messing around with Core Data, and I am sure I am missing something obvious, because I cannot find an example that at all resembles what I am trying to do.
Let's say I'm playing around with a DVD database. I have two entities. A Movie (title, year, rating, and a relationship to Actor) and Actor (name, sex, picture).
Getting all the Movies is easy. It's just:
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Winery"
inManagedObjectContext:self.managedObjectContext];
Getting all the Movies with "Kill" in the title is easy, I just add a NSPredicate:
NSPredicate *predicate = [NSPredicate predicateWithFormat:
#"name LIKE[c] "*\"Kill\"*""];
But Core Data seems to abstract out the id fields for the managed objects... so how to I query against an attribute that is an object (or: query against a relationship)?
In other words, assuming that I already have the Actor object I am concerned with ([Object id 1 - 'Chuck Norris'] for instance), what is the Predicate format for "Give me all movies starring [Object id 1 - 'Chuck Norris']"?
Assuming that there is a one-to-many inverse relationship between the Actor and the Movie entities, you can just get the entity for Chuck Norris the same way you would get any specific entity, and then access the array of Movie entities attached to the relationship on the Actor entity.
// Obviously you should do proper error checking here... but for this example
// we'll assume that everything actually exists in the database and returns
// exactly what we expect.
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Actor" inManagedObjectContext:self.managedObjectContext];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name LIKE[c] 'Chuck Norris'"];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
[request setPredicate:predicate];
// You need to have imported the interface for your actor entity somewhere
// before here...
NSError *error = nil;
YourActorObject *chuck = (YourActorObject*) [[self.managedObjectContext executeFetchRequest:request error:&error] objectAtIndex:0];
// Now just get the set as defined on your actor entity...
NSSet *moviesWithChuck = chuck.movies;
As a note, this example obviously assumes 10.5 using properties, but you can do the same thing in 10.4 using accessor methods.
Or you can use another predicate:
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Actor" inManagedObjectContext:self.managedObjectContext];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name = %#",#"Chuck Norris"]
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
[request setPredicate:predicate];
YourActorObject *chuck = [[self.managedObjectContext executeFetchRequest:request error:nil] objectAtIndex:0];
[request release];
NSSet *moviesWithChuck = chuck.movies;