I can't understand why my query is not working

1.7k views Asked by At

so i have a bunch of objects on parse.com. class name is "MainInfo" with geo points in a column named geoPoint.

I am getting the users location by adding the following to my .h file:

@property (nonatomic, strong) PFGeoPoint *userLocation;

Then adding the following to viewDidLoad:

[PFGeoPoint geoPointForCurrentLocationInBackground:^(PFGeoPoint *geoPoint, NSError *error) {
if (!error) {
    self.userLocation = geoPoint;
    [self loadObjects];
}
}];

and performing the rolling queryForTable:

- (PFQuery *)queryForTable
{
// User's location
PFGeoPoint *userGeoPoint = self.userLocation;
// Create a query for places
PFQuery *query = [PFQuery queryWithClassName:@"MainInfo"];
// Interested in locations near user.
[query whereKey:@"geoPoint" nearGeoPoint:userGeoPoint];
// Limit what could be a lot of points.
query.limit = 10;
// Final list of objects
_placesObjects = [query findObjects];

return query;
}

Xcode gives me the error *** setObjectForKey: object cannot be nil (key: $nearSphere)

I've got no idea what I am doing wrong, as far as I can see it should work.

I worked along with the parse documentation to get me this far. Here is a link

2

There are 2 answers

0
Héctor Ramos On BEST ANSWER

The error arises because you're passing a nil value to whereKey:nearGeoPoint: as self.userLocation is unlikely to be set the first time the view loads. You will want to do two things:

  1. In your queryForTable method, check if self.userLocation is nil. If it is, return nil. This acts as a no-op and the table won't show any data just yet.

    - (PFQuery *)queryForTable
    {
        if (!self.userLocation) {
            return nil;
        }
        // User's location
        PFGeoPoint *userGeoPoint = self.userLocation;
        // Create a query for places
        PFQuery *query = [PFQuery queryWithClassName:@"MainInfo"];
        // Interested in locations near user.
        [query whereKey:@"geoPoint" nearGeoPoint:userGeoPoint];
        // Limit what could be a lot of points.
        query.limit = 10;
        // Final list of objects
        _placesObjects = [query findObjects];
    
        return query;
    }
    
  2. In your geoPointForCurrentLocationInBackground: completion block, once the self.userLocation value is set, you will want to call [self loadObjects]. This will tell the PFQueryTableViewController to run your query again, and this time around self.userLocation will not be nil, allowing you to construct your original query. Fortunately, you've already performed this step, but I've included it here in case anyone else has the same question.

2
Wain On

When you make the geoPointForCurrentLocationInBackground call it has a completion block. This completion block marks the point at which you have the required information to populate the table view (or you know that there is an error and you should do something else). So, you shouldn't display / load query data into the table view until the completion block is called. Other wise you don't have the required information to complete the query.

You could display an activity indicator while you're waiting. Or, it might be better to get the userLocation before even showing this view so you always have the information for the query when you get here.