Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a variable for Element name in Core Data Predicate

I am trying to write a method which tries to retrieve an object based on a predicate using a variable (as part of a NSXMLParser). The code looks like this:

I have these variables defined in the class:

@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;

@property (strong, nonatomic) NSString *model;
@property (strong, nonatomic) NSString *element;

Now in the method, I set up the request like this:

NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:self.model inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity];

Now the challenge - what I want to be able to do is:

// DOES NOT WORK
[request setPredicate:[NSPredicate predicateWithFormat:@"%@ == %@", self.element,string]];

But that does not return any results. After some mucking around, I notice that this does work:

 if ( [self.element isEqualToString:@"name"] ) {
     [request setPredicate:[NSPredicate predicateWithFormat:@"name == %@", string]];
 }

This tells me that my self.element is set correctly (I think?) but that the predicate doesn't like the left hand side of the expression being a variable.

I also tried:

[request setPredicate:[NSPredicate predicateWithFormat:@"%s == %@", [self.element UTF8String],string]];

... just to see if perhaps it preferred a string. I couldn't make that work either.

Is what I am attempting even possible? I've read as much as I can of the Core Data documentation and I can't find any sample code which does it this way, but I also didn't find anything to say it wasn't possible.

EDIT: and now the working code:

[request setPredicate:[NSPredicate predicateWithFormat:@"%K == %@", self.element,string]];
like image 772
valdarin Avatar asked Feb 13 '12 14:02

valdarin


1 Answers

If you haven't done before, read the Predicate Programming Guide and you can find everything about predicates.

Now, if I've understood correctly, you want to create a predicate between two string but the first isn't a defined string but it can change.
I haven't used them before but I believe you can solve your problem by using a predicate with dynamic property names.

Here from the documentation:

Dynamic Property Names
Because string variables are surrounded by quotation marks when they are substituted into a format string using %@, you cannot use %@ to specify a dynamic property name—as illustrated in the following example.

NSString *attributeName = @"firstName";  
NSString *attributeValue = @"Adam";  
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%@ like %@", attributeName, attributeValue];  

The predicate format string in this case evaluates to "firstName" like "Adam".

If you want to specify a dynamic property name, you use %K in the format string, as shown in the following fragment.

predicate = [NSPredicate predicateWithFormat:@"%K like %@", attributeName, attributeValue];  

The predicate format string in this case evaluates to firstName like "Adam" (note that there are no quotation marks around firstName).

More info can be found also here: Predicate Format String Summary.

like image 112
matteodv Avatar answered Oct 23 '22 07:10

matteodv