I tried to get distance and duration from my position to selected marker on map using Google Directions API. I am using Alamofire + SwiftyJSON for doing the HTTP request and parsing the JSON that I get back.
I use this method for requesting and parsing JSON:
func fetchDistanceFrom(from: CLLocationCoordinate2D, to: CLLocationCoordinate2D, completionHandler: (String?, String?, NSError?) -> ()) -> ()
{
let urlString = "https://maps.googleapis.com/maps/api/directions/json?key=\(apiKey)&origin=\(from.latitude),\(from.longitude)&destination=\(to.latitude),\(to.longitude)&mode=walking"
var parsedDistance : String?
var parsedDuration : String?
request(.GET, urlString)
.responseJSON { (req, res, json, error) in
if(error != nil) {
NSLog("Error: \(error)")
}
else {
var json = JSON(json!)
parsedDistance = json["routes"][0]["legs"][0]["distance"]["text"].stringValue as String!
parsedDuration = json["routes"][0]["legs"][0]["duration"]["text"].stringValue as String!
dispatch_async(dispatch_get_main_queue()) {
completionHandler(parsedDistance, parsedDuration, error)
}
}
}
}
And I use it in my MapView class like this:
func mapView(mapView: GMSMapView!, didTapMarker marker: GMSMarker!) -> Bool {
let selectedMarker = marker as! ExtendedMarker
dataProvider.fetchDistanceFrom(mapView.myLocation.coordinate, to: marker.position){ (parsedDistance, parsedDuration, error) in
let busStopDistance = parsedDistance
let busStopDuration = parsedDuration
selectedMarker.distance = "Distance: \(busStopDistance!)"
selectedMarker.duration = "Duration: \(busStopDuration!)"
}
return false
}
to show the info afterwards in this method:
func mapView(mapView: GMSMapView!, markerInfoContents marker: GMSMarker!) -> UIView! {
let selectedMarker = marker as! ExtendedMarker
if let infoView = UIView.viewFromNibName("MarkerInfoView") as? MarkerInfoView {
infoView.nameLabel.text = selectedMarker.name
infoView.linesTextView.text = selectedMarker.lines
infoView.distanceLabel.text = selectedMarker.distance
infoView.durationLabel.text = selectedMarker.duration
return infoView
} else {
return nil
}
}
But it doesn't work as it is supposed to, because somehow I can't get the distance and time on the first time I click the marker on map. It always shows up on second click on the marker. It looks like I get the JSON object from Google, it just isn't parsed before MapView shows the marker info.
Please, is there any way to fix this? I would be very thankful for any advice. Thank you.