I want to create a route between the user position and a marker when it is touched using JSON and google directions server API on swift (Google MAPS API).
I have a extension with this code:
extension MapViewController: GMSMapViewDelegate {
func mapView(mapView: GMSMapView!, didTapMarker marker: GMSMarker!) -> Bool {
reverseGeocodeCoordinate(marker.position)
originAddresslong = "\(userLocation.coordinate.longitude)"
originAddresslat = "\(userLocation.coordinate.latitude)"
destinationAddresslong = "\(marker.position.longitude)"
destinationAddresslat = "\(marker.position.latitude)"
var directionsURLString = baseURLDirections + "origin=" + originAddresslat + "," + originAddresslong + "&destination=" + destinationAddresslat + "," + destinationAddresslong + "&key=Mykey"
directionsURLString = directionsURLString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
let directionsURL = NSURL(string: directionsURLString)
func crearruta(withCompletionHandler completionHandler: ((status: String, success: Bool) -> Void)) {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let directionsData = NSData(contentsOfURL: directionsURL!)
let dictionary: Dictionary<NSObject, AnyObject>
do {
dictionary = try NSJSONSerialization.JSONObjectWithData(directionsData!, options: NSJSONReadingOptions.MutableContainers) as! Dictionary<NSObject, AnyObject>
// Get the response status.
let status = dictionary["status"] as! String
if status == "OK" {
let allResults = dictionary["results"]as! Array<Dictionary<NSObject, AnyObject>>
self.lookupAddressResults = allResults[0]
// Keep the most important values.
self.overviewPolyline = self.lookupAddressResults["overview_polyline"] as! Dictionary<NSObject, AnyObject>
let legs = self.selectedRoute["legs"] as! Array<Dictionary<NSObject, AnyObject>>
self.fetchedFormattedAddress = self.lookupAddressResults["formatted_address"] as! String
let geometry = self.lookupAddressResults["geometry"] as! Dictionary<NSObject, AnyObject>
self.fetchedAddressLongitude = ((geometry["location"] as! Dictionary<NSObject, AnyObject>)["lng"] as! NSNumber).doubleValue
self.fetchedAddressLatitude = ((geometry["location"] as! Dictionary<NSObject, AnyObject>)["lat"] as! NSNumber).doubleValue
}
else {
completionHandler(status: status, success: false)
}
} catch {
completionHandler(status: "", success: false)
}
})
}
let route = overviewPolyline["points"] as! String
let path: GMSPath = GMSPath(fromEncodedPath: route)
if routePolyline != nil {
routePolyline.map = nil
routePolyline = nil
}
routePolyline = GMSPolyline(path: path)
routePolyline.strokeWidth = 5
routePolyline.strokeColor = UIColor.yellowColor()
routePolyline.map = mapView
return false
}
1- userlocation.coordinate is working, because i can read longitude and latitude in a label.
2- marker position is showing coordinates too in a label.
3- Mykey is my api key for Google directions (on a web search it works)
what is the problem? the conversion to string values of coordinates? the crearruta function?
The error message is:
fatal error: unexpectedly found nil while unwrapping an Optional value
Thanks for all.
Edit: I have made a change to the originaddress and destinationaddress variables. Now if I use
UIApplication.sharedApplication().openURL(NSURL(string: directionsURLString)!)
I can see the Json properly. I need now to use it.
OK. I wanna create a polyline with the JSON information. I have read that i need only the polyline points. I must use a dictionary to get the info and then draw the line.
I have used this code but also fails.
func crearruta(withCompletionHandler completionHandler: ((status: String, success: Bool) -> Void)) {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let directionsData = NSData(contentsOfURL: directionsURL!)
let dictionary: Dictionary<NSObject, AnyObject>
do {
dictionary = try NSJSONSerialization.JSONObjectWithData(directionsData!, options: NSJSONReadingOptions.MutableContainers) as! Dictionary<NSObject, AnyObject>
// Get the response status.
let status = dictionary["status"] as! String
if status == "OK" {
self.selectedRoute = (dictionary["routes"] as! Array<Dictionary<NSObject, AnyObject>>)[0]
self.overviewPolyline = self.selectedRoute["overview_polyline"] as! Dictionary<NSObject, AnyObject>
let legs = self.selectedRoute["legs"] as! Array<Dictionary<NSObject, AnyObject>>
let startLocationDictionary = legs[0]["start_location"] as! Dictionary<NSObject, AnyObject>
self.originCoordinate = CLLocationCoordinate2DMake(startLocationDictionary["lat"] as! Double, startLocationDictionary["lng"] as! Double)
let endLocationDictionary = legs[legs.count - 1]["end_location"] as! Dictionary<NSObject, AnyObject>
self.destinationCoordinate = CLLocationCoordinate2DMake(endLocationDictionary["lat"] as! Double, endLocationDictionary["lng"] as! Double)
self.originAddress = legs[0]["start_address"] as! String
self.destinationAddress = legs[legs.count - 1]["end_address"] as! String
//ruta con curvas en coche
let route = self.overviewPolyline["points"] as! String
self.path = GMSPath(fromEncodedPath: route)
completionHandler(status: status, success: true)
}
else {
completionHandler(status: status, success: false)
}
} catch {
completionHandler(status: "", success: false)
}
})
}
if routePolyline != nil {
routePolyline.map = nil
routePolyline = nil
}
routePolyline = GMSPolyline(path: path)
routePolyline.strokeWidth = 5
routePolyline.strokeColor = UIColor.yellowColor()
routePolyline.map = mapView
return false
}