Reputation: 53
I'am trying to query an array of PFGeoPoints stored on the Parse backend. I have the User table, with data assigned to it such as "location", "name". everything is being sent to Parse upon posting from my app and is properly stored in the backend. I am having issues retrieving all location from Parse and storing them into an MKAnnotation on the map. Find below my code
import UIKit
import Parse
import CoreLocation
import MapKit
class mapViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
@IBOutlet var mapUsers: MKMapView!
var MapViewLocationManager:CLLocationManager! = CLLocationManager()
var currentLoc: PFGeoPoint! = PFGeoPoint()
override func viewDidLoad() {
super.viewDidLoad()
// ask user for their position in the map
PFGeoPoint.geoPointForCurrentLocationInBackground {
(geoPoint: PFGeoPoint?, error: NSError?) -> Void in
if let geoPoint = geoPoint {
PFUser.currentUser()? ["location"] = geoPoint
PFUser.currentUser()?.save()
}
}
mapUsers.showsUserLocation = true
mapUsers.delegate = self
MapViewLocationManager.delegate = self
MapViewLocationManager.startUpdatingLocation()
mapUsers.setUserTrackingMode(MKUserTrackingMode.Follow, animated: false)
}
override func viewDidAppear(animated: Bool) {
let annotationQuery = PFQuery(className: "User")
currentLoc = PFGeoPoint(location: MapViewLocationManager.location)
annotationQuery.whereKey("Location", nearGeoPoint: currentLoc, withinMiles: 10)
annotationQuery.findObjectsInBackgroundWithBlock {
(PFUser, error) -> Void in
if error == nil {
// The find succeeded.
print("Successful query for annotations")
let myUsers = PFUser as! [PFObject]
for users in myUsers {
let point = users["Location"] as! PFGeoPoint
let annotation = MKPointAnnotation()
annotation.coordinate = CLLocationCoordinate2DMake(point.latitude, point.longitude)
self.mapUsers.addAnnotation(annotation)
}
} else {
// Log details of the failure
print("Error: \(error)")
}
}
}
Upvotes: 3
Views: 465
Reputation: 3593
Instead of putting the call in your viewDidAppear()
method - as previous commenters said, your location may be nil, returning no results - I would use a tracker of some sort and put it in your didUpdateLocations()
MKMapView delegate method. Here, I use GCD's dispatch_once()
so that when my location is found for the first time with a reasonable accuracy, my code is executed (here you will put your call to Parse).
Declare GCD's tracker variable
var foundLocation: dispatch_once_t = 0
Now use something like this in your location manager's delegate method didUpdateLocations()
if userLocation?.location?.horizontalAccuracy < 2001 {
dispatch_once(&foundLocation, {
// Put your call to Parse here
})
}
PS. You should also consider doing any updates to UI on the main thread. Parse fetches that data on a background thread and although you might never see a problem, it's both safer and good habit to do any UI changes on main thread. You can do this with the following:
dispatch_async(dispatch_get_main_queue(), {
// Put any UI update code here. For example your pin adding
}
Upvotes: 1