iOS/Parse query not finding string match in array - ios

I am trying to query a PFObject that contains an array. I am looking to match a given NSString against any object within the PFObject's array of strings. According to http://blog.parse.com/2012/03/28/parse-supports-many-to-many-relations/, I can use whereKey:equalTo to look for matches within an array.
I have replaced the variable I would usually use with the string that I know to be in the array whose object I am querying. It is a character-for-character match. Yet the query returns no matches.
My code:
PFQuery *convosQuery = [PFQuery queryWithClassName:#"convo"];
PFObject *currentUserFacebookID = [NSString stringWithFormat:#"11808098"];
[convosQuery whereKey:#"nonUserFacebookIDs" equalTo:currentUserFacebookID];
[convosQuery findObjectsInBackgroundWithBlock:^(NSArray *convos, NSError *error) {
for (PFObject *convo in convos) {
NSLog(#"user/convo match found");
As I said, this returns no matches even though a PFObject of class "convo" contains for key "nonUserFacebookIDs" the value "[["11808098"]]".
What could be going on?

Does this object have any ACLs that might be restricting reads to a subset of users?

You mentioned "[["11808098"]]". Does this mean an array of array containing a string? If so, it would not match the string you specified.
And BTW, though not related to your question, why did use the below line? Why should you assign a string to a PFObject?
PFObject *currentUserFacebookID = [NSString stringWithFormat:#"11808098"];
~ Sunil Phani Manne

Related

IOS/Objective-C: Search string element with array of objects

As part of an autocomplete box, I am searching names within an array of contacts. However, after the user picks a name from the suggested List, I need to grab the id of the contact which is in the array of contact objects but not the array of names that appear in the suggest box. I've been working with just the names as that's what I want to display in the suggestion box but have an array of contacts as well.
How would I convert code below (probably using key values) to search the name dimensions of an array of objects instead of an array of names so as to keep track of the ids of the objects. I am kind of fuzzy on arrays and key values.
//the array being searched looks something like #[#"John", #"Dave", #"Sam", #"Xian", #"Ahmed", #"Johann"];
//I want to search the names in an array that looks something like:
(
{
first = "John";cid = 2;},
{
first = "Dave";cid = 44;},
{
first = "Xian";cid=99})
//this code works great to search names but I lose track ids. Thank you for any suggestions.
-(void)searchArray: (NSMutableArray*) array forString: (NSString *) term {
[_contactsSuggested removeAllObjects];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains[c] %#",term];
NSArray *tempArray = [array filteredArrayUsingPredicate:predicate];
_contactsSuggested = [NSMutableArray arrayWithArray:tempArray];
[_autocompleteTableView reloadData];
}
Create a Contact object. Give it a name property, an id property, and any other properties you need. Then write code that searches an array of Contact objects rather than just an array of names. You could then create a predicate using predicateWithBlock to filter the items that match your name property.

PFQuery constraints - exclude subquery

I have a table called "match". this table has several columns of type string.
I'm trying to create a query that queries for the string value "undefined" in column "player2". That works without problem. When I query for just that I get the results.
But I want to add a constraint so that it excludes the match objects where the current user's facebook id matches that of column "player1". I've stored the id in the PFUser object so i can easily retrieve it.
I'm creating a random player matching system where the query checks for an open spot in the match table's "player2" column. if it's "undefined" I know that there is an open slot in the match and the player can join it.
However it needs to exclude the matches the current player previously started himself. Otherwise it would join a match the current player started himself.
//check for objects that match the string "undefined"
PFQuery *query1 = [PFQuery queryWithClassName:#"match"];
[query1 whereKey:#"player2" containsString:#"UNDEFINED"];
//AND constraint to exclude the match of query1 if the current user id matches
PFQuery *query2 = [PFQuery queryWithClassName:#"match"];
[query2 whereKey:#"player1" notEqualTo:[[PFUser currentUser] objectForKey#"fbId"]];
PFQuery *mainQuery = [PFQuery orQueryWithSubqueries:#[query1,query2]];
Your player1 and player2 cols are strings containing user ids. I think this is going to cause other problems, but you can still do the query you're attempting as follows...
NSString *userId = [PFUser currentUser].objectId;
NSPredicate *predicate = [NSPredicate predicateWithFormat:
#"(player1 = 'UNDEFINED') AND (player2 != %#)", userId];
PFQuery *query = [PFQuery queryWithClassName:#"match" predicate:predicate];
EDIT - I changed fbId above to be the user's object id. That's what you're probably storing in the player string col. It's this kind of confusion that makes storing strings (instead of pointers) a problem for the design.

NSPredicate crash on CONTAINS?

I'm trying to do a simple predicate filter on an array of objects.
The objects in the array have 2 properties, displayValue and value. I am trying to filter based on a search string and I get a crash.
NSPredicate *pred = [NSPredicate predicateWithFormat:#"displayValue CONTAINS[cd] %#", searchString];
NSArray *results = [_data filteredArrayUsingPredicate:pred];
what exactly is incorrect about this format that it causes a Can't use in/contains operator with collection 100 (not a collection) crash?
I was able to reproduce your problem. This happens if the displayValue of one of the objects
is not a NSString, but some different type.
From your error message, I assume that you assigned an NSNumber, for example
obj.displayValue = #100;
somewhere in your code. The "CONTAINS" predicate works only with strings, so you must assign
only string values to the property.
Therefore, you should define the type of the property as
NSString * instead of id, and check the assignments to that property.
If you really need to keep the id type and store different kinds of objects in that property,
then you cannot use the "CONTAINS" operator in the predicate. A direct comparison
with #"displayValue == %#" would work, however.
UPDATE: As a workaround, you could use the description method, which converts any object
to a string, in particular it converts a NSNumber to its string representation. So the following could work:
[NSPredicate predicateWithFormat:#"displayValue.description CONTAINS[cd] %#", searchString];
The drawback is that the exact description format is not documented.
Another solution could be to use a block-based predicate, where you can check the type
of each object and perform the appropriate comparison.

Error when trying to sort array using predicates

I'm struggeling with an error occurring when trying to populate an array with the filtered results of another array.
I've defined a global array named allArray in the .h-file, this array is containing about 100 objects. Then, I want the user to be able to search for a specific object, and I've tried to develop it using predicates:
-(IBAction)searchChanged:(id)sender {
//The searchfield's value has been changed.
NSString *searchString = searchField.text;
NSPredicate *searchPredicate = [NSPredicate predicateWithFormat:#"self CONTAINS[c] %#", searchString];
NSMutableArray *tempSearchArray = [allArray filterUsingPredicate:searchPredicate];
[filteredArray removeAllObjects];
[filteredArray addObjectsFromArray:tempSearchArray];
}
I end up getting an error when I create tempSearchArray.
Initializing 'NSMutableArray *__strong' with an expression of
incompatible type 'void'
filterUsingPredicate doesn't return an array, it returns nothing(void).
From the description:
"Evaluates a given predicate against the array’s content and leaves only objects that match"
You should instead use:
filteredArrayUsingPredicate
As the Docs will tell you, filterUsingPredicate has a void return value.
See here:
NSMutableArray Class reference
That means that you cannot assign that return value to another array.
You need to use this method on the original array, along the lines of
[allArray filterUsingPredicate:somePredicate];
arrArray will be stripped of any elements that dont match the predicate.
Now proceed with these results as you wish.
Have Fun
filterUsingPredicate returns a void and not an array. You might want to consider using a filteredArrayUsingPredicate instead

NSPredicate filter array but return only one field of an object

I'm sure this question has been asked but I don't know what to search on.
I have array of Message objects with the following fields {selected[BOOL], messageText[STR]}. I want to filter this array to get only the objects with selected=TRUE. So far so good.
NSArray *messagesFiltered = [self.fetchedResultsController.fetchedObjects filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"selected == TRUE"]];
However, I don't need the objects themselves in the returned array, I need an array of the messageText strings. How to modify predicate to return only the messageText strings and not the whole object?
That's not really the job of a predicate. Predicates are only for filtering, not modifying, the array you apply them to.
However, there's a fun little trick: the method -valueForKey: will apply the kind of transform you want to your array. Just call it with the messageText key that you want:
NSArray *messagesFiltered = [self.fetchedResultsController.fetchedObjects filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"selected == TRUE"]];
NSArray *realMessages = [messagesFiltered valueForKey:#"messageText"];
On an array, -valueForKey: asks each element for a value for the given key, then returns an array of everything the elements returned. (Any element that returns nil for the key you pass shows up as [NSNull null] in the resulting array.)

Resources