I am performing a simple PFQuery to fetch a bunch of Box objects (class name).
My Box has a pointer to a Toy object called toy.
I let my user select a bunch a toys, then the search only display the Box objects with those Toy objects.
So I end up with an NSArray of PFObjects of type Toy. I have an array of objectId strings for the objects, and I just create another array like this:
PFObject *obj = [PFObject objectWithoutDataWithClassName:#"Toy" objectId:objectId];
Now I can query the object, I would have thought. I have tried doing a query of Box objects with an NSPredicate which looks like this:
[NSPredicate predicateWithFormat:[NSString stringWithFormat:#"toy = %#", toyObject]];
My app crashes and tells me it is unable to parse that. So before adding the predicate I take the objectId instead and try doing that:
[NSPredicate predicateWithFormat:[NSString stringWithFormat:#"toy.objectId = %#", toyObject.objectId]];
However, it doesn't like that format either. So how can I create an NSPredicate that lets me only fetch objects with a specific pointer result like explained.
In other words just use
PFUser *user = [PFUser currentUser];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"fromUser = %#", user];
where in this example, "user" is a pointer stored in the table and we're searching for it under the "fromUser" column
I think you're making this too hard on yourself. If I'm reading your question correctly, there is a much simpler way to do this, and you don't have to use NSPredicate at all:
NSMutableArray *toys = [NSMutableArray array];
// Figure out some way (during selection) to get the "toy" objects into the array
PFQuery *query = [PFQuery queryWithClassName:#"Box"];
[query whereKey:#"toy" containedIn:toys];
[query findObjects... // You should know the rest here
And that's it! Nice and easy, should find all Box instances that have a toy that is contained in the toys array.
Turns out it was pretty simple.
Don't use [NSString stringWithFormat:(NSString *)] if you are creating an NSPredicate format string. NSPredicate really doesn't like it and can often fail to parse your format.
Related
Suppose I have the following objects
class A {
NSArray *arrayOfB;
}
class B {
NSString *name;
}
Now, I have an array of As like below and each A contains 10 objects of B within its property arrayOfB.
NSArray *arrayOfAs; //contains objects of A
How can I get the objects of A depending upon specific match of name property of Bs inside of A, by using NSPredicate ?
I've tried googling, etc. and even writing various style of NSPredicate but did not succeed. Can anyone enlighten me how to do it?
This is what I tried so far:
NSPredicate *p = [NSPredicate predicateWithFormat:#"(SELF.name BEGINSWITH[c] %# IN SELF.arrayOfB)",myText];
NSArray *mySearchedArrayOfAs = [arrayOfAs filteredArrayUsingPredicate:p];
But I run into error which says "Unable to parse the predicate".
I think you need to use ANY operator, like this:
NSPredicate *p = [NSPredicate predicateWithFormat:#"ANY arrayOfB.name BEGINSWITH[c] %#", myText];
I have a model object Place that have a couple of standards properties. It also have some custom instance method defined in a Mogenerated subclass. That looks something like this:
- (NSString *) currentName {
return [self valueFromArrayData:self.nameLocaleMap atIndex:...];
}
I wonder if it's possible to make a NSpredicate would function something like this somehow:
// I have tried this predicate, and it doesn't work... IS it possible to do something similar to get the wanted effect?
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"currentName CONTAINS[cd] %#", searchText];
Or alternatively, if it's possible to evaluate/compare the contents of a NSData property with a NSString?
Your predicate should work, but only when run locally against, for example, an array (filteredArrayUsingPredicate:).
Your predicate can not be used with Core Data because currentName doesn't exist at the data store level.
I want to display name and lastName in my UITableViewCell. I have an array with a lot of data that I retrieve from a database, and pretty much everything I need is in the array, the trick is to filter and show the results as I want.
I have the following code to filter what is being typed on searchBar and add to an NSMutableArray:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"usuario.username contains [cd] %#", searchText];
NSArray *filtroUsuario = [name filteredArrayUsingPredicate:predicate];
searchResults = [filtroUsuario valueForKeyPath:#"#distinctUnionOfObjects.usuario.nome"];
I use #distinctUnionOfObjects because the objects that I'm filtering are not user objects, therefore I want to retrieve user values, so as some objects point to the same user, I get duplicate names.
The code to put information on the UITableView is like this:
cell.textLabel.text = searchResults[indexPath.row];
It all works fine. My trouble is that now I want to show one more key on the cell, so the keypath would be usuario.sobrenome. How would I put both values together?
I've tried playing with the line:
searchResults = [filtroUsuario valueForKeyPath:#"#distinctUnionOfObjects.usuario.nome"];
and got some interesting results, but not the one I'm expecting.
It looks like you should be able to use #distinctUnionOfObjects.usuario, so your results is an array of user objects (or some other objects with the keys that you require). Then in the table view cell setup you do:
id user = searchResults[indexPath.row];
cell.textLabel.text = [user valueForKey:#"nome"];
cell.otherTextLabel.text = [user valueForKey:#"sobrenome"];
I have an NSMangedObject that contains NSSet of other NSManagedObjects.
I need to check if these objects has an value in NSSet and then return them.
I use MagicalRecord for fetching data.
So I need something like this:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"stringObjects contains %#", string];
So if NSSet stringObjects contains some string that I am looking for so then return object I have requested.
One note here: stringObjects (name just for example it represent my NSSet) it is NSSet that contains NSManagedObjects, so I need to search them by some id (for example string_id attribute).
So then model looks like this
NSSet *set = MainObject.stringObjects;
NSString *string_id_for_first_object = [[[set allObjects] objectAtIndex:0] string_id];
Just for better understanding relationship.
But the question is about how can I create predicate to check if NSSet contains needed id.
If I understand your question correctly, stringObjects is a to-many relationship
from one entity A to another entity B, and B has an attribute string_id.
To find all A objects that are related to any B object with the given string id, use:
NSString *stringId = …; // The string that you are looking for
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"ANY stringObjects.string_id == %#", stringId];
EntityA has a to-many relationship to EntityB (and EntityB has a to-one relationship to EntityA). I have an array of EntityBs (or more accurately, I have an NSArray that contains instances of NSManagedObject which represent EntityB). I want to create an NSFetchRequest that will fetch all EntityAs that have a relationship to at least one of the EntityBs in the array. How do I write the predicate for this fetch request?
The following works, but I think it is sub-optimal; it's hard to grok and I'm sure there must be a better way of expressing this:
NSArray *entityBs = ...;
NSMutableArray *containsEntityBSubPredicates = [NSMutableArray new];
for (NSManagedObject *entityB in entityBs) {
[containsEntityBSubPredicates addObject:[NSPredicate predicateWithFormat:#"%# IN entityBs", entityB]];
}
NSPredicate *containsEntityBsPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:containsEntityBSubPredicates];
I've also tried this, but it doesn't work:
NSArray *entityBs = ...;
NSPredicate *containsEntityBsPredicate = [NSPredicate predicateWithFormat:#"ANY %# in entityBs", entityBs];
Am I missing a simpler solution?
You were almost there with your predicate, just switch the parameters:
[NSPredicate predicateWithFormat:#"ANY entityBs in %#", entityBArray];
Look at Apple's example code with IN here for further explanation.