How to construct a PFQuery for locations? - ios

I am constructing a PFQuery to get users within a radius(200 meters), i have set a Location column in Parse custom class in which i store geo locations. I get the users but when i calculate their distances manually through Haversine formula, it turns out to be more than 200 meters. This is my Pfquery:
PFQuery *query = [PFQuery queryWithClassName:#"UserLocations"];
[query whereKey:#"Location" nearGeoPoint:geopoint withinKilometers:0.2];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
compBlock(objects,error);
}];
What am i doing wrong?

Related

IOS Parse is my nested query a good solution for comparing an object with a pointer?

Currently, I am querying the database twice to achieve a list of all users nearby who are not already being followed by the current user. Here is my nested query:
// List of all users being followed by the current user
PFQuery *followingActivitiesQuery = [PFQuery queryWithClassName:kFTActivityClassKey];
[followingActivitiesQuery whereKey:kFTActivityTypeKey equalTo:kFTActivityTypeFollow];
[followingActivitiesQuery whereKey:kFTActivityFromUserKey equalTo:[PFUser currentUser]];
[followingActivitiesQuery setCachePolicy:kPFCachePolicyNetworkOnly];
[followingActivitiesQuery includeKey:kFTActivityToUserKey];
[followingActivitiesQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
NSMutableArray *followedUserIds = [[NSMutableArray alloc] init];
// Obtain an array of object ids for all users being followed
for (PFObject *object in objects) {
PFUser *followedUser = [object objectForKey:kFTActivityToUserKey];
[followedUserIds addObject:followedUser.objectId];
}
PFGeoPoint *geoPoint = [[PFUser currentUser] objectForKey:kFTUserLocationKey];
// List of all users within 50 miles that are not already being followed
PFQuery *followUsersByLocationQuery = [PFQuery queryWithClassName:kFTUserClassKey];
[followUsersByLocationQuery whereKey:kFTUserObjectIdKey notEqualTo:[PFUser currentUser].objectId];
[followUsersByLocationQuery whereKey:kFTUserLocationKey nearGeoPoint:geoPoint withinMiles:50];
[followUsersByLocationQuery whereKeyExists:kFTUserLocationKey];
[followUsersByLocationQuery whereKey:kFTUserObjectIdKey notContainedIn:followedUserIds];
[followUsersByLocationQuery setLimit:100];
[followUsersByLocationQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
self.objects = objects;
[self.tableView reloadData];
}
}];
}
}];
My question is, is this a viable solution? I feel guilty about having to query the server twice in order to achieve this, but I was not able to do it all in one query. I could not compare a parse pointer from the ActivityClass to the Users class, since the Users class is the class being pointed to, and because of this I couldn't think of a way to do it all in one query.
You're in luck - this can be done in a single query using the whereKey:doesNotMatchKey:inQuery: method of PFQuery.
Parse will treat this as a single, compound query against the database. Totally guilt-free :)
Try this instead:
// List of all users being followed by the current user
PFQuery *followingActivitiesQuery = [PFQuery queryWithClassName:kFTActivityClassKey];
[followingActivitiesQuery whereKey:kFTActivityTypeKey equalTo:kFTActivityTypeFollow];
[followingActivitiesQuery whereKey:kFTActivityFromUserKey equalTo:[PFUser currentUser]];
[followingActivitiesQuery setCachePolicy:kPFCachePolicyNetworkOnly];
[followingActivitiesQuery includeKey:kFTActivityToUserKey];
PFGeoPoint *geoPoint = [[PFUser currentUser] objectForKey:kFTUserLocationKey];
// List of all users within 50 miles that are not already being followed
PFQuery *followUsersByLocationQuery = [PFQuery queryWithClassName:kFTUserClassKey];
[followUsersByLocationQuery whereKey:kFTUserObjectIdKey notEqualTo:[PFUser currentUser].objectId];
[followUsersByLocationQuery whereKey:kFTUserLocationKey nearGeoPoint:geoPoint withinMiles:50];
[followUsersByLocationQuery whereKeyExists:kFTUserLocationKey];
//The next line is your new compound query
[followUsersByLocationQuery whereKey:kFTUserObjectIdKey doesNotMatchKey:#"objectId" inQuery:followingActivitiesQuery];
[followUsersByLocationQuery setLimit:100];
[followUsersByLocationQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
self.objects = objects;
[self.tableView reloadData];
}
}];

Parse Query - cannot process more than one whereKey:doesNotMatchKey:inQuery

I was trying this
PFQuery *allDealsQuery = [Deal query];
PFRelation *favoritedDealsRelation = [user objectForKey:#"favoritedDeals"];
PFQuery *favoritedDealsQuery = [favoritedDealsRelation query];
PFRelation *redeemedDealsRelation = [user objectForKey:#"redeemedDeals"];
PFQuery *redeemedDealsQuery = [redeemedDealsRelation query];
[allDealsQuery whereKey:#"objectId" doesNotMatchKey:#"objectId" inQuery:favoritedDealsQuery];
//Parse does not support more than 2 where queries???
[allDealsQuery whereKey:#"objectId" doesNotMatchKey:#"objectId" inQuery:redeemedDealsQuery];
[allDealsQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
onSuccess(objects);
}
else {
onError(error);
}
}];
When I tried to use two queries, the answer was different from what was expected.
So should I use be using only one doesNotMatchKey query?
Try referencing parse documentation on Compound Queries:
https://parse.com/docs/ios_guide#queries-compound/iOS
Compound Queries
If you want to find objects that match one of several queries, you can use orQueryWithSubqueries: method. For instance, if you want to find players with either have a lot of wins or a few wins, you can do:
PFQuery *lotsOfWins = [PFQuery queryWithClassName:#"Player"];
[lotsOfWins whereKey:#"wins" greaterThan:#150];
PFQuery *fewWins = [PFQuery queryWithClassName:#"Player"];
[fewWins whereKey:#"wins" lessThan:#5];
PFQuery *query = [PFQuery orQueryWithSubqueries:#[fewWins,lotsOfWins]];
[query findObjectsInBackgroundWithBlock:^(NSArray *results, NSError *error) {
// results contains players with lots of wins or only a few wins.
}];

IOS Parse include key query

I am trying to print the name of a category using Parse in iOS and Objectve-C. Thanks for looking. Let me know if you have any questions.
CategoryInBudget Table
category(pointer)
amount(number)
user(pointer)
Category Table
name(string)
Here is my code:
PFQuery *query = [PFQuery queryWithClassName:#"CategoryInBudget"];
[query whereKey:#"user" equalTo:[PFUser currentUser]];
[query includeKey:#"Category"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
for (PFObject *object in objects) {
NSLog(#"%#", object[#"Category"][#"name"];
}
}];

Parse, query to find games of one user

In parse i have a "Game" class with array pointer column called "Players". I want to get games that contain [PFUser currentUser] in arrayKey called "Players", always this column stored a three players array.
I tried some query, i couldn't get success.
PFQuery *query = [PFQuery queryWithClassName:#"Game"];
[query whereKey:#"Players" containsAllObjectsInArray:#[[PFUser currentUser]]];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error)
{...}];
Also tried.
[query whereKey:#"Players" containsAllObjectsInArray:#[[PFUser currentUser].objectId]];
I'm sure already stored a Game with current User inside.
Thanks in advanced.
Just do this:
PFQuery *query = [PFQuery queryWithClassName:#"Game"];
[query whereKey:#"Players" equalTo:[PFUser currentUser]];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error)
{...}];
If you run equalTo on an array key, it checks to see if the value is in the array.
Make sure to check that you stored a pointer to the user, and not their objectId. If you're storing id's instead, do equalTo:[PFUser currentUser].objectId];

how to query based on pfobject/pfuser associated with another pfobject in parse.com?

I have a Parse class called FriendRelation. This class has two users, one a friend the other a user.
I want to get all of the messages posted by all of the friends of a user. I am attempting to do so with the following query:
PFQuery *innerQuery = [PFQuery queryWithClassName:#"FriendRelation"];
[innerQuery whereKey:#"user" equalTo:currentUser];
PFQuery *query = [PFQuery queryWithClassName:#"Message"];
[query whereKey:#"userMessage" matchesQuery:innerQuery];
[query findObjectsInBackgroundWithBlock:^(NSArray *comments, NSError *error) {
}];
This query comes back with no results.
I believe this is occurring because of the line:
[query whereKey:#"userMessage" matchesQuery:innerQuery];
The where key needs to be a FriendRelation to match. Is this correct?
How can I make the results of the inner query be a user that will intern match the matching query?
Thanks!
You can try using
- (void)whereKey:(NSString *)key matchesKey:(NSString *)otherKey inQuery:(PFQuery *)query
Something like:
PFQuery *innerQuery = [PFQuery queryWithClassName:#"FriendRelation"];
[innerQuery whereKey:#"user" equalTo:currentUser];
PFQuery *query = [PFQuery queryWithClassName:#"Message"];
[query whereKey:#"userMessage" matchesKey:#"firendUser" inQuery:innerQuery];
[query findObjectsInBackgroundWithBlock:^(NSArray *comments, NSError *error) {
//do something useful..
}];
Let me know how it goes!

Resources