简体   繁体   中英

How can I get the user's current location, perform a local geo query and then apply the results to a PFQueryTableViewController?

I have been working on the following code and have ended up confused! The idea of this code extract is to grab the user's current location, search for points within a 10km radius and then to list them through a PFQueryTableView.

My code is in two parts here due to my confusion. The first part does retrieve the number of results I would expect, as the println statement on the objects count reflects that it finds 1 item for the current GPS location I have set up through my simulator debug tools.

The second part of the function then does a similar query based on a fixed location but that is not how I want it to work.

Ideally if I can do this using just the geoPointForCurrentLocationInBackground block would be fantastic.

Question is, how do I get this to work? I am in the process of learning Swift and IOS development having come from a different development background.

override func queryForTable() -> PFQuery! {

    PFGeoPoint.geoPointForCurrentLocationInBackground {
      (point:PFGeoPoint!, error:NSError!) -> Void in
      if error == nil {
        var query = PFQuery(className: "Town")
        query.limit = 10
        query.whereKey("gps", nearGeoPoint: point, withinKilometers: 10.0)
        query.findObjectsInBackgroundWithBlock{
          (objects: [AnyObject]!, error: NSError!) -> Void in
          if (error == nil) {
            println(objects.count)
          }
        }
      }
    }

    let userGeoPoint = PFGeoPoint(latitude:40.0, longitude:-30.0)

    var query = PFQuery(className:"Town")
    // Interested in locations near user.
    query.whereKey("gps", nearGeoPoint:userGeoPoint, withinKilometers: 5.0)
    // Limit what could be a lot of points.
    query.limit = 10
    // Final list of objects
    //let placesObjects = query2.findObjects()
    return query
  }

The problem you've got here is that the determination of the users location is happening asynchronously, but you need to return a query from that method synchronously (so it's likely your method will return the query before you have the users location). I'd suggest you restructure your code to do a couple of things.

  1. Get the users location earlier, like in viewDidLoad() , or view[Will/Did]Appear() , and reload the tableView when you have the location.
  2. Return a query that gives 0 results (or use a default location, or disregard location), if you don't know the users location. The appropriate behaviour here is application specific.

So, you'll need something like below.

class MyViewController: PFQueryTableViewController {
  var usersLocation: PFGeoPoint? {
    didSet {
      // This will reload the tableview when you set the users location. 
      // Handy if you want to keep updating it.
      if (tableView != nil) {
        tableView.reloadData()
      }
    }
  }

  override func viewDidLoad() {
    super.viewDidLoad()
    PFGeoPoint.geoPointForCurrentLocationInBackground { point, error in
      if error == nil {
        self.usersLocation = point
      }
    }
  }

  override func queryForTable() -> PFQuery! {
    var query = PFQuery(className:"Town")
    // If we don't have a location, just query without it.
    if let location = usersLocation {
      query.whereKey("gps", nearGeoPoint:location, withinKilometers: 5.0)
    }
    query.limit = 10
    return query
  }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM