Hi,
I'm trying to show directions on a MKMapView from a users current location to a desired location chosen by the user. I've got it working to when user selects a location, it will open it in the Apple Maps app. I would like he directions to show on the MapView within my app.
The code is below. I'm under time pressure also so an answer would be really great ASAP.
import UIKit
import MapKit
class LocationSearchTable : UITableViewController {
var handleMapSearchDelegate:HandleMapSearch! /
var matchingItems:[MKMapItem] = []
var mapView: MKMapView!
func parseAddress(selectedItem:MKPlacemark) -> String {
/
let firstSpace = (selectedItem.subThoroughfare != nil && selectedItem.thoroughfare != nil) ? " " : ""
/
let comma = (selectedItem.subThoroughfare != nil || selectedItem.thoroughfare != nil) && (selectedItem.subAdministrativeArea != nil || selectedItem.administrativeArea != nil) ? ", " : ""
/
let secondSpace = (selectedItem.subAdministrativeArea != nil && selectedItem.administrativeArea != nil) ? " " : ""
let addressLine = String(
format:"%@%@%@%@%@%@%@",
/
selectedItem.subThoroughfare ?? "",
firstSpace,
/
selectedItem.thoroughfare ?? " ",
comma,
secondSpace,
/
selectedItem.locality ?? " ",
secondSpace,
/
selectedItem.administrativeArea ?? " "
)
return addressLine
}
}
extension LocationSearchTable : UISearchResultsUpdating {
func updateSearchResultsForSearchController(searchController: UISearchController) {
guard let mapView = mapView,
let searchBarText = searchController.searchBar.text else { return }
let request = MKLocalSearchRequest()
request.naturalLanguageQuery = searchBarText
request.region = mapView.region
let search = MKLocalSearch(request: request)
search.startWithCompletionHandler { response, _ in
guard let response = response else {
return
}
self.matchingItems = response.mapItems
self.tableView.reloadData()
}
}
}
extension LocationSearchTable {
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return matchingItems.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell")!
let selectedItem = matchingItems[indexPath.row].placemark
cell.textLabel?.text = selectedItem.name
cell.detailTextLabel?.text = parseAddress(selectedItem)
return cell
}
}
extension LocationSearchTable {
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let selectedItem = matchingItems[indexPath.row].placemark
print(selectedItem.title);
print("£££££££££££££££££££")
print(selectedItem.location!.coordinate.latitude);
print("£££££££££££££££££££")
print(mapView);
print(mapView!.userLocation.coordinate.latitude);
print(mapView!.userLocation.coordinate.longitude);
handleMapSearchDelegate!.dropPinZoomIn(selectedItem)
dismissViewControllerAnimated(true, completion: nil)
let request: MKDirectionsRequest = MKDirectionsRequest()
let userPlacemark = MKPlacemark(coordinate: (mapView.userLocation.coordinate), addressDictionary: [:])
let source = MKMapItem(placemark: userPlacemark)
let destination = MKMapItem(placemark: selectedItem)
/
request.source = source /
request.destination = destination /
/
request.transportType = MKDirectionsTransportType.Walking;
/
/
request.requestsAlternateRoutes = true
let directions = MKDirections(request: request)
let route = MKRoute()
print("----------------------------------5");
print(directions);
print("£££££0");
self.provideDirections((selectedItem.title)!);
/ directions.calculateDirectionsWithCompletionHandler { (response, error) in
print("jakeeksmkkvmkfmmvmfvfmvkfmvkfmvkfmvkfmkmkm668686")
let launchOptions = [
MKLaunchOptionsDirectionsModeKey,
MKLaunchOptionsDirectionsModeWalking]
}*/
/
/
/
}
func showRoute(response:MKDirectionsResponse){
print("----------------------------------");
for route in (response.routes as [MKRoute]){
print(route);
print("----------------------------------2");
/
mapView.addOverlay(route.polyline, level: MKOverlayLevel.AboveRoads)
print("----------------------------------3");
let routeSeconds = route.expectedTravelTime
let routeDistance = route.distance
print("distance between two points is \(routeSeconds) and \(routeDistance)")
}
}
func provideDirections(destination:String){
print(destination);
let request = MKDirectionsRequest()
request.source = MKMapItem.mapItemForCurrentLocation()
CLGeocoder().geocodeAddressString(destination,
completionHandler: {placemarks, error in
guard let placemarks = placemarks else{
/ Handle the error here perhaps by displaying an alert */
return
}
/ Convert the CoreLocation destination
placemark to a MapKit placemark */
let placemark = placemarks[0]
let destinationCoordinates =
placemark.location!.coordinate
/ Get the placemark of the destination address */
let destination = MKPlacemark(coordinate:
destinationCoordinates,
addressDictionary: nil)
request.destination = MKMapItem(placemark: destination)
/ Set the transportation method to automobile */
request.transportType = .Walking
/ Get the directions */
let directions = MKDirections(request: request)
directions.calculateDirectionsWithCompletionHandler{
response, error in
/
guard let response = response else {
/
return
}
/ You can manually parse the response, but in
here we will take a shortcut and use the Maps app
to display our source and
destination. We didn't have to make this API call at all,
as we already had the map items before, but this is to
demonstrate that the directions response contains more
information than just the source and the destination. */
/ Display the directions on the Maps app */
let launchOptions = [
MKLaunchOptionsDirectionsModeKey:
MKLaunchOptionsDirectionsModeWalking]
MKMapItem.openMapsWithItems(
[response.source, response.destination],
launchOptions: launchOptions)
([response.source,response.destination], launchOptions: launchOptions)
}
})
}
}