Mams1101
Mams1101

Reputation: 53

Displaying geopoint of all users in a map parse

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

Answers (1)

Byron Coetsee
Byron Coetsee

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

Related Questions