I have the following method that saves points to Parse.com using the PFGeoPoint object:
I capture them using:
func convertPoint(touch: UITouch) {
let location = touch.locationInView(self.mapView) as CGPoint
let coordinate: CLLocationCoordinate2D = self.mapView.convertPoint(location, toCoordinateFromView: self.mapView)
self.coordinates.addObject(NSValue(MKCoordinate: coordinate))
}
Then I use the following to add them to Parse:
func addPolygonToMap() {
let HUD: MBProgressHUD = showActivityIndicator(true, self.view)
var numberOfPoints: NSInteger = self.coordinates.count
if (numberOfPoints > 4) {
var points: [CLLocationCoordinate2D] = []
// Save to Parse object.
var geofenceUserObject = PFObject(className: "GeofenceUser")
let geofenceId = self.generateUUID()
geofenceUserObject["UserId"] = "IjlpQHwyfG"
geofenceUserObject["GeofenceId"] = geofenceId
geofenceUserObject.saveInBackgroundWithBlock({ (succeeded: Bool, error: NSError!) in
if (error != nil) {
println("Error saving: \(error)")
} else if (succeeded) {
for i in 0..<numberOfPoints {
let coordinateValue = self.coordinates[i].MKCoordinateValue
points.insert(coordinateValue, atIndex: i)
var geoPoint = PFGeoPoint(latitude: coordinateValue.latitude, longitude: coordinateValue.longitude)
var geofenceObject = PFObject(className: "GeofenceCoordinates")
geofenceObject["Point"] = geoPoint
geofenceObject["GeofenceId"] = geofenceId
geofenceObject.saveInBackgroundWithBlock({ (operation, error) in
println("Saved Geofence objects: \(operation)")
println("Points: \(numberOfPoints)")
println("Index: \(i+1)")
if (i+1 == numberOfPoints) {
self.polygon = MKPolygon(coordinates: &points, count: numberOfPoints)
self.mapView.addOverlay(self.polygon)
self.isDrawingPolygon = false
self.createDrawButton("DRAW", color: UIColor(red: 11/255, green: 188/255, blue: 185/255, alpha: 1))
self.canvasView.image = nil
self.canvasView.removeFromSuperview()
HUD.hide(true)
}
})
}
}
})
}
}
This is an example MKpolygon that gets created (approx. 319 points):
This is the method I'm using to add the points to the map:
var query = PFQuery(className: "GeofenceCoordinates")
query.orderByAscending("createdAt")
query.whereKey("GeofenceId", equalTo: geofenceId)
query.findObjectsInBackgroundWithBlock({ (objects, error) in
if let objects = objects as? [PFObject] {
var coordinates: Array<CLLocationCoordinate2D> = []
for point in objects {
if let coordinate = point.objectForKey("Point") as? PFGeoPoint {
let c = CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: coordinate.longitude)
coordinates.append(c)
}
}
let polygon = MKPolygon(coordinates: &coordinates, count: coordinates.count)
self.mapView.addOverlay(polygon)
}
})
The problem is that when I retrieve these points from Parse I get the following MKPolygon instead, which is missing quite a few points and looks incomplete.
I'm not quite sure whether it's my way of persisting the data or the way I'm retrieving the data.
Okay, so I completely refactored the way I was saving coordinate data to Parse.
I changed the column to be an Array instead of a GeoPoint and it
Saves about 300% faster.
Retrieves all the coordinates properly.
Related
i try to get data from parse server. Therefore it takes 2 backgroundthreads. But i dont get it managed to wait for the completion in a right way. So i have splitted it up like following code:
func load(loadCompletion: #escaping () -> ()) {
let delegate = object as! AppDelegate
parseQuery.findObjectsInBackground { (result: [PFObject]?, error: Error?) in
self.getAllData(result: result, delegate: delegate, error: error) {
loadCompletion()
}
}
}
func getAllData(result: [PFObject]?, delegate: AppDelegate, error: Error?, allDataCompletion: #escaping () -> ()) {
if error == nil && result != nil {
for obj in result! {
let date: Date = obj["Date"] as! Date
let coordinates: PFGeoPoint = obj["Coordinates"] as! PFGeoPoint
let imageFile: PFFileObject = obj["Image"] as! PFFileObject
let lat: CLLocationDegrees = coordinates.latitude
let long: CLLocationDegrees = coordinates.longitude
let cllCoordinates = CLLocationCoordinate2D(latitude: lat, longitude: long)
self.getImageData(imageFile: imageFile) { (image) in
let poo = Poo(coordinates: cllCoordinates, dateTime: date, image: image)
delegate.poos.append(poo)
}
}
allDataCompletion()
}
}
func getImageData(imageFile: PFFileObject, imageDataCompletion: #escaping (UIImage?) -> () ) {
var image: UIImage? = nil
imageFile.getDataInBackground { (data, error) in
if error == nil && data != nil {
image = UIImage(data: data!)
}
imageDataCompletion(image)
}
}
So, i want so set up the array in the delegate, but unfortunately the loadCompletion() gets called before the array is filled. Please help me to get this running in right order. Thanks!
A simple solution is to modify your getAllData function and call allDataCompletion after getting image data for the last object.
func getAllData(result: [PFObject]?, delegate: AppDelegate, error: Error?, allDataCompletion: #escaping () -> ()) {
if error == nil && result != nil {
for (idx, obj) in result!.enumerated() {
let date: Date = obj["Date"] as! Date
let coordinates: PFGeoPoint = obj["Coordinates"] as! PFGeoPoint
let imageFile: PFFileObject = obj["Image"] as! PFFileObject
let lat: CLLocationDegrees = coordinates.latitude
let long: CLLocationDegrees = coordinates.longitude
let cllCoordinates = CLLocationCoordinate2D(latitude: lat, longitude: long)
self.getImageData(imageFile: imageFile) { (image) in
let poo = Poo(coordinates: cllCoordinates, dateTime: date, image: image)
delegate.poos.append(poo)
if idx == result!.endIndex-1{
allDataCompletion()
}
}
}
}
}
or Use DispatchGroup / Synchronizing Async Code
I have task model in database (using realm), which consists of id, title, distance, longitude, latitude, customerAddress. I'm trying update my distance to task. I'm new to swift so I do not understand how should I fix geoCoder.geocodeAddressString closure, so that all tasks would update with their distance. (when task does not have latitude and longitude I check if task has customeradress by using geocodeAddressString
func updateTasksDistance() {
// get tasks for db
guard let tasks = Task.getAllUserTasks() else { return }
// last tracked location
guard let lastLocation = lastLocation else { return }
let myLocation = CLLocation(latitude: lastLocation.coordinate.latitude, longitude: lastLocation.coordinate.longitude)
var distance = 0
tasks.forEach({ (task) in
// check if task has longitude and latitude
if let lat = Double(task.latitude), let long = Double(task.longitude), lat != 0 && long != 0 {
let taskLocation = CLLocation(latitude: lat, longitude: long)
distance = Int(taskLocation.distance(from: myLocation))
} else if !task.customerAddress.isEmpty { // check if task has address
geoCoder.geocodeAddressString(task.customerAddress) { placemarks, _ in
if let placemark = placemarks?.first, let location = placemark.location {
self.taskLocationCoordinate = CLLocation(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude )
}
}
}
// check if we have closure location??
if let taskLocation = taskLocationCoordinate {
distance = Int(CLLocation(latitude: taskLocation.coordinate.latitude, longitude: taskLocation.coordinate.longitude).distance(from: myLocation))
taskLocationCoordinate = nil
}
// update my distance to task
updateTaskDistanceDb(task: task, with: distance)
// reset distance
distance = 0
})
}
// update task distance in db
fileprivate func updateTaskDistanceDb(task: Task, with distance: Int) {
let realm = try? Realm()
if let realm = realm {
do {
try realm.write {
task.distance = distance
}
} catch {
print("error")
}
}
}
Current result: distance gets updated correctly where closure is not called, but when closure is getting called then I get out of order results
expected result: all tasks distance relative to mine updated correctly
Fixed this issue by using this code:
fileprivate func geoCode(addresses: [String], results: [CLPlacemark] = [], completion: #escaping ([CLPlacemark]) -> Void ) {
guard let address = addresses.first else {
completion(results)
return
}
let geoCoder = CLGeocoder()
geoCoder.geocodeAddressString(address) { placemarks, _ in
var updatedResults = results
if let placemark = placemarks?.first {
updatedResults.append(placemark)
}
let remainingAddresses = Array(addresses[1..<addresses.count])
self.geoCode(addresses: remainingAddresses, results: updatedResults, completion: completion)
}
}
func updateTasksDistance() {
// get tasks for db
guard let tasks = Task.getAllUserTasks() else { return }
// last tracked location
guard let lastLocation = lastLocation else { return }
let myLocation = CLLocation(latitude: lastLocation.coordinate.latitude, longitude: lastLocation.coordinate.longitude)
let dispatchGroup = DispatchGroup()
for task in tasks where !task.customerAddress.isEmpty {
let addresses = [task.customerAddress]
dispatchGroup.enter()
geoCode(addresses: addresses) { results in
guard let customerAdress = results.first else { return }
guard let customerLocatin = customerAdress.location else { return }
let taskLocation = CLLocation(latitude: customerLocatin.coordinate.latitude,
longitude: customerLocatin.coordinate.longitude )
// do additional sutff
dispatchGroup.leave()
}
}
dispatchGroup.notify(queue: DispatchQueue.main, execute: {
// got all the address
}
})
}
Recursive geocode function helped to calculate all coordinates and dispatchGroup.notify is for waiting till all addresses are geocoded.
i have 3 annotation and i draw polyline between first and second annotation but i need the therd one move over that polyline but it's always move in street polyline to the destnation
-my code
func moveDelivery(_ destinationCoordinate : CLLocationCoordinate2D{
self.deliveryAnnotation.coordinate = CLLocationCoordinate2DMake(29.959640, 31.270421)
let sourcePlaceMark = MKPlacemark(coordinate: self.userAnnotation.coordinate)
//sourcePlaceMark.title
let destPlaceMkark = MKPlacemark(coordinate: self.deliveryAnnotation.coordinate)
let sourceItem = MKMapItem(placemark: sourcePlaceMark)
let destItem = MKMapItem(placemark: destPlaceMkark)
let directionRequest = MKDirections.Request()
directionRequest.source = sourceItem
directionRequest.destination = destItem
directionRequest.transportType = .any
let direction = MKDirections(request: directionRequest)
direction.calculate(completionHandler: {
response, error in
guard let response = response else {
if let error = error {
print(error.localizedDescription)
} else {
self.deliveryAnnotation.courseDegrees = self.getHeadingForDirectionFromCoordinate(self.kitchenAnnotation.coordinate, toLoc: self.userAnnotation.coordinate)
self.view.transform = CGAffineTransform(rotationAngle:CGFloat(self.deliveryAnnotation.courseDegrees))
}
return
}
guard let primaryRoute = response.routes.first else { return }
let route = response.routes[0]
self.mapView.addOverlay(route.polyline, level: .aboveRoads)
let rekt = route.polyline.boundingMapRect
self.mapView.setRegion(MKCoordinateRegion(rekt), animated: true)
})
//
UIView.animate(withDuration: Double(60), animations: {
self.deliveryAnnotation.coordinate = destinationCoordinate
}, completion: { success in
if success {
}
})
}
Your third annotation isn't following the route because you're animating it moving in a straight line between the first and second line. Try getting the coordinates from the MKRoute's polyline and animate between each one (According to apple's docs MKRoutes are made up of coordinates, but you might be able to use points as well)
If you'd like it to animate over the span of 60 seconds:
func moveDelivery(_ destinationCoordinate: CLLocationCoordinate2D) {
// I don't know why you have the delivery annotation start here, is this for testing?
deliveryAnnotation.coordinate = CLLocationCoordinate2DMake(29.959640, 31.270421)
let sourcePlaceMark = MKPlacemark(coordinate: destinationCoordinate)
let destPlaceMkark = MKPlacemark(coordinate: userAnnotation.coordinate)
let directionRequest = MKDirections.Request()
directionRequest.source = MKMapItem(placemark: sourcePlaceMark)
directionRequest.destination = MKMapItem(placemark: destPlaceMkark)
directionRequest.transportType = .any
let direction = MKDirections(request: directionRequest)
direction.calculate(completionHandler: {
response, error in
guard let response = response else {
print("MKRequest gave no response")
if let error = error {
print(error.localizedDescription)
} else {
self.deliveryAnnotation.courseDegrees = self.getHeadingForDirectionFromCoordinate(self.kitchenAnnotation.coordinate, toLoc: self.userAnnotation.coordinate)
self.view.transform = CGAffineTransform(rotationAngle:CGFloat(self.deliveryAnnotation.courseDegrees))
}
return
}
guard let primaryRoute = response.routes.first else {
print("response has no routes")
return
}
self.mapView.addOverlay(primaryRoute.polyline, level: .aboveRoads)
let rekt = primaryRoute.polyline.boundingMapRect
self.mapView.setRegion(MKCoordinateRegion(rekt), animated: true)
let coordinateArray = primaryRoute.polyline.coordinates
assert(coordinateArray.count > 0, "coordinate array is empty")
self.routeCoordinates = coordinateArray
// initiate recursive animations
self.coordinateIndex = 0
})
}
var routeCoordinates = [CLLocationCoordinate2D]()
var avgAnimationTime: Double {
return 60 / Double(routeCoordinates.count)
}
var coordinateIndex: Int! {
didSet {
guard coordinateIndex != routeCoordinates.count else {
print("animated through all coordinates, stopping function")
return
}
animateToNextCoordinate()
}
}
func animateToNextCoordinate() {
let coordinate = routeCoordinates[coordinateIndex]
UIView.animate(withDuration: avgAnimationTime, animations: {
self.deliveryAnnotation.coordinate = coordinate
}, completion: { _ in
self.coordinateIndex += 1
print("moved between coordinates")
})
}
EDIT
make sure to include this extension, otherwise you won't be able to get the coordinates of the MKRoute (source: https://gist.github.com/freak4pc/98c813d8adb8feb8aee3a11d2da1373f)
public extension MKMultiPoint {
var coordinates: [CLLocationCoordinate2D] {
var coords = [CLLocationCoordinate2D](repeating: kCLLocationCoordinate2DInvalid,
count: pointCount)
getCoordinates(&coords, range: NSRange(location: 0, length: pointCount))
return coords
}
}
EDIT #2
See above, edited original answer to animate through each coordinate after the previous finishes animating. Really rough but it should work.
EDIT #3
Added your code to get the destination variable as well as some assert and debug printing calls. If things aren't working this time, please tell me which debug messages you get.
EDIT #4
I just demo'd my code and it works. Here is the MapViewController class I used along with necessary extensions:
private let reuseId = "deliveryReuseId"
private let userTitle = "user"
private let startingPointTitle = "store"
private let deliveryTitle = "delivery truck"
class MapViewController: UIViewController {
var mapView: MKMapView!
// annotations for this demo, replace with your own annotations
var deliveryAnnotation: MKPointAnnotation = {
let annotation = MKPointAnnotation()
annotation.title = deliveryTitle
return annotation
}()
let userAnnotation: MKPointAnnotation = {
let annotation = MKPointAnnotation()
annotation.title = userTitle
annotation.coordinate = CLLocationCoordinate2DMake(29.956694, 31.276854)
return annotation
}()
let startingPointAnnotation: MKPointAnnotation = {
let annotation = MKPointAnnotation()
annotation.title = startingPointTitle
annotation.coordinate = CLLocationCoordinate2DMake(29.959622, 31.270363)
return annotation
}()
override func viewDidLoad() {
super.viewDidLoad()
loadMapView()
navigate()
}
func loadMapView() {
// set map
mapView = MKMapView()
view = mapView
mapView.delegate = self
mapView.register(MKAnnotationView.self, forAnnotationViewWithReuseIdentifier: reuseId)
// add annotations
mapView.addAnnotation(userAnnotation)
mapView.addAnnotation(startingPointAnnotation)
mapView.addAnnotation(deliveryAnnotation)
}
func navigate() {
let sourcePlaceMark = MKPlacemark(coordinate: startingPointAnnotation.coordinate)
let destPlaceMkark = MKPlacemark(coordinate: userAnnotation.coordinate)
let directionRequest = MKDirections.Request()
directionRequest.source = MKMapItem(placemark: sourcePlaceMark)
directionRequest.destination = MKMapItem(placemark: destPlaceMkark)
directionRequest.transportType = .any
let direction = MKDirections(request: directionRequest)
direction.calculate(completionHandler: { response, error in
if let error = error {
print(error.localizedDescription)
return
}
guard let primaryRoute = response!.routes.first else {
print("response has no routes")
return
}
self.mapView.addOverlay(primaryRoute.polyline, level: .aboveRoads)
self.mapView.setRegion(MKCoordinateRegion(primaryRoute.polyline.boundingMapRect), animated: true)
// initiate recursive animation
self.routeCoordinates = primaryRoute.polyline.coordinates
self.coordinateIndex = 0
})
}
var routeCoordinates = [CLLocationCoordinate2D]()
var avgAnimationTime: Double {
// to show delivery in 60 second, replace 60 with amount of seconds you'd like to show
return 60 / Double(routeCoordinates.count)
}
var coordinateIndex: Int! {
didSet {
guard coordinateIndex != routeCoordinates.count else {
print("animated through all coordinates, stopping function")
return
}
animateToNextCoordinate()
}
}
func animateToNextCoordinate() {
let coordinate = routeCoordinates[coordinateIndex]
UIView.animate(withDuration: avgAnimationTime, animations: {
self.deliveryAnnotation.coordinate = coordinate
}, completion: { _ in
self.coordinateIndex += 1
})
}
}
extension MapViewController: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
// replace these images with your own
switch annotation.title {
case userTitle:
annotationView.image = UIImage(named: "user")
case startingPointTitle:
annotationView.image = UIImage(named: "store")
case deliveryTitle:
annotationView.image = UIImage(named: "deliveryTruck")
default: break
}
return annotationView
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
guard overlay is MKPolyline else {
return MKOverlayRenderer()
}
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = .black
renderer.lineWidth = 5
renderer.lineJoin = .round
return renderer
}
}
public extension MKMultiPoint {
var coordinates: [CLLocationCoordinate2D] {
var coords = [CLLocationCoordinate2D](repeating: kCLLocationCoordinate2DInvalid,
count: pointCount)
getCoordinates(&coords, range: NSRange(location: 0, length: pointCount))
return coords
}
}
I'm trying to to calculate the distance from an event to my current location, sort the results and populate that in a tableview. I keep getting error for optional unwrapped value distance is nil.
private func observeEvents() {
refHandle = ref.observe(.childAdded, with: { (snapshot) -> Void in
let eventDetails = snapshot.value as! Dictionary<String, AnyObject>
let eventID = snapshot.key
let location = eventDetails["location"] as! String!
//calculating distance
self.forwardGeocoding(address: location!)
let distance = self.eventLocation?.distance(from: self.currentLocation!) as Double!
//end calculating
let dateTime = eventDetails["dateTime"] as! String!
let addedByUser = eventDetails["addedByUser"] as! String!
let attending = eventDetails["attendance"] as! String!
if let name = eventDetails["eventName"] as! String! , name.characters.count > 0
{
self.events.append(Events(id:eventID, name: name, location: location!, dateTime: dateTime!, addedByUser: addedByUser!, attending: attending! , distance: distance!))
self.events.sort(by: { $0.distance < $1.distance})
self.tableView.reloadData()
} else {
print("Error ! Can't load events from database")
}
})
} //load events data to uitableview
I created a function to return a CLLocation from an address
func forwardGeocoding(address: String) {
CLGeocoder().geocodeAddressString(address, completionHandler: { (placemarks, error) in
if error != nil {
print(error!)
return
}
if (placemarks?.count)! > 0 {
let placemark = placemarks?[0]
self.eventLocation = placemark?.location
}
})
}
I finally figured out the answer. The issue was the function for distance is called asynchronously there for the result would always be nil. I created a completion handler for the forwardGeocoding function to return latitude and longitude from the address string and call the result inside the nested firebase listener. Here is the code, I hope if someone ran into something similar problem to me will find it helpful.
//Get lat and long
func getCoordinates(address: String, completionHandler: #escaping (_ lat: CLLocationDegrees?, _ long: CLLocationDegrees?, _ error: Error?) -> ()) -> Void {
var _:CLLocationDegrees
var _:CLLocationDegrees
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(address) { (placemarks: [CLPlacemark]!, error: Error!) in
if error != nil {
print("Geocode failed with error: \(error.localizedDescription)")
} else if placemarks.count > 0 {
let placemark = placemarks[0] as CLPlacemark
let location = placemark.location
let lat = location?.coordinate.latitude
let long = location?.coordinate.longitude
completionHandler(lat, long, nil)
}
}
}
Nested call in firebase listener
refHandle = ref.observe(.childAdded, with: { (snapshot) -> Void in
let location = event["address"] as! String
self.getCoordinates(address: location!) { lat, long, error in
if error != nil {
print("Error")
} else {
self.latitude = lat
self.longitude = long
let distance = CLLocation(latitude: self.latitude!,longitude: self.longitude!).distance(from: self.currentLocation!)
if let name = eventDetails["eventName"] as! String! , name.characters.count > 0
{
self.events.append(Events(id:eventID, name: name, location: location!, dateTime: dateTime!, addedByUser: addedByUser!, attending: attending!, distance: distance))
self.events.sort(by: { $0.distance < $1.distance})
self.tableView.reloadData()
} else {
print("Error ! Can't load events from database")
}
}
}
})
I'm fairly new to IOS development and I have little to no clue what this error means. The error shows up when I try to use Parse to get an object within a 1.0 km distance from the user.
PFGeoPoint.geoPointForCurrentLocationInBackground { (geoPoint: PFGeoPoint?, error: NSError?) -> Void in
var query = PFQuery(className: "VenueData")
query.whereKey(key: "Name", nearGeoPoint: geoPoint, withinKilometers: 1.0)
var object = query.findObjects()
println(object)
}
However, whenever i use the withinKilometers constraint this error below keeps popping up and I do not know why that happens. Any help would be greatly appreciated.
$nearSphere: only works on geopoints fields (Code: 102, Version: 1.7.4)
My guess is this is working because your Name field is likely a string, not a PFGeoPoint field. If you look in your data browser on Parse you'll be able to determine this. PFGeoPoint has to be a latititude and a longitude in the data browser in order for this to work.
I would not use the withinKilometers. Instead I would use the withinMiles method.
It is a lot easier for using geopoints from Parse in Swift.
If you still want to use Kilometers just convert Kilometers to Miles. In this case instead of:
withinKilometers: 1.0
use:
withinMiles: 0.62
This code below should work:
query.whereKey("Name", nearGeoPoint: geoPoint, withinMiles: 0.62)
If the code above does not work:
try this out, this is the coding that I used to display points on a map that is a set couple miles away from the users current location. But you will have to set up some things in the info.plist file to get the users current location. Here is the example code that you can try out.
import UIKit
import MapKit
import CoreLocation
import Parse
import ParseUI
import Bolts
var currentLoc: PFGeoPoint = PFGeoPoint()
class MapViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet weak var mapView: MKMapView!
var query: PFQuery = PFQuery()
var manager:CLLocationManager!
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(true)
query = PFQuery(className: "ClassName")
query.whereKey("dateOfClass", greaterThanOrEqualTo: NSDate())
query.whereKey("classes", nearGeoPoint: currentLoc, withinMiles: 400)
query.findObjectsInBackgroundWithBlock {
(posts, error) -> Void in
if error == nil {
let myPosts = posts as! [PFObject]
for post in myPosts {
var subtitleString: String = String()
if let dateObject = post["dateOfClass"] as? NSDate {
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM/dd/yyyy HH:mm a"
var dateNSDate: String = dateFormatter.stringFromDate(dateObject)
subtitleString = dateNSDate
}
let point = post["classes"] as! PFGeoPoint
var coordinate: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: point.latitude, longitude: point.longitude)
var workoutClassName: String = post.objectForKey("workoutClassName") as! String
var workoutClassInstructor: String = post.objectForKey("instructorName") as! String
var objectsID: String = post.objectId! as String
var annotation: MapPin = MapPin(coordinate: coordinate, title: "\(workoutClassName), \(workoutClassInstructor)", subtitle: "\(subtitleString)", annotationID: "\(objectsID)")
self.mapView.addAnnotation(annotation)
}
} else {
// Log details of the failure
println("Error: \(error)")
}
}
println(currentLoc)
}
override func viewDidLoad() {
super.viewDidLoad()
mapView.showsUserLocation = true
var latitude: CLLocationDegrees = currentLoc.latitude
var longitude: CLLocationDegrees = currentLoc.longitude
var latDelta:CLLocationDegrees = 0.7
var lonDelta:CLLocationDegrees = 0.7
var span:MKCoordinateSpan = MKCoordinateSpanMake(latDelta, lonDelta)
var location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
var region:MKCoordinateRegion = MKCoordinateRegionMake(location, span)
mapView.setRegion(region, animated: false)
}
}