Getting routing information

By Nicholas Duchon

Let me try to make this as simple as possible. In this case:

Recipe:

  1. MapKit.framework - add this framework to your project.
  2. dot-h file - wherever you want to use references to this stuff
    1. #import <MapKit/MapKit.h>
  3. dot-m file - wherever you want to get a route, in this case, I have just added some code to a view controller in a single-view template project.
  4. Because of the requirements of the various classes, here's an outline of the parts of this code:
    1. did load calls findRoute - a new method just to keep things distinct from each other
    2. MKDirections is the class that will call the server and return with a set of directions - the object is reference through the variable request
      1. to use this class, we need to set up the request, which means an MKDirectionRequest object (request)
        1. the source and destination attributes of the request are MKMapItem objects, which will be initialized using MKPlacemart objects (sMK and dMK)
          1. the  objects (sMK and dMK) need to be initialized - in this version using CLLoationCoordinate2D objects (srce2d and dest2d)
              1. Those objects can be declared and initialized using {x, y} notation, see below.
      2. After the source and destination are specified for the MKDirections object (directions), using initWithRequest:, we call the method:
        calculateDirectionsWithCompletionHandler
        1. the result is a pointer (^) to a MKDirectionsResponse data structure (often just one object, but it may contain alternate routes)
        2. the request goes over the net and sets up a response (event) handler - immediate code block in this case.
        3. the response code block checks for an error, and if there is none, calls the showRoute: method, again just to limit the complexity of this part of the code
    3. showRoute: - the method that goes through the data structure returned by the route request
      1. first for loop goes through every route returned (there may be alternates)
      2. the inner for loop goes through all the directions in the route.steps array, an array of MKRouteStep objects, and sends the NSString part of each step to NSLog.
      3. Your code could do more interesting things with the resulting route, including display the directions in a table, or display the route on a map.
        1. The data structure is rather complicated, so you should look at the documentation for MKDirectionsResponse for more details.
  5. I may produce another web page to describe how to put a route onto a map.

Code - in view controller dot m file:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
   
    [self findRoute]; // ND: call new function
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void) findRoute
{
    MKDirectionsRequest * request = [[MKDirectionsRequest alloc] init];

//    CLLocationCoordinate2D srce2d = {38.89751790, -77.0365419}; // Capitol, Washington DC
//    CLLocationCoordinate2D dest2d = {39.136772  , -77.714715 }; // Purcellville, VA
   
    CLLocationCoordinate2D srce2d = {51.500866, -0.142292}; // Buckingham Palace, England
    CLLocationCoordinate2D dest2d = {51.178865, -1.82677 }; // Stonehenge, England

    MKPlacemark * sMK = [[MKPlacemark alloc] initWithCoordinate:srce2d addressDictionary:NULL];
    MKPlacemark * dMK = [[MKPlacemark alloc] initWithCoordinate:dest2d addressDictionary:NULL];
   
    request.source      = [[MKMapItem alloc] initWithPlacemark:sMK];
    request.destination = [[MKMapItem alloc] initWithPlacemark:dMK];
   
    request.requestsAlternateRoutes = NO;
   
    MKDirections * directions = [[MKDirections alloc] initWithRequest:request];
   
    [directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse * response, NSError *error) {
        if (error) {
            NSLog(@"We have an error: %@\n", [error description]);
        } else {
            [self showRoute:response];
        }
    }];
   
} // end method findRoute

- (void) showRoute: (MKDirectionsResponse *) response {
    for (MKRoute * route in response.routes) {
        NSLog(@"Route: %@\n", [route description]);
        for (MKRouteStep * step in route.steps) {
            NSLog(@"Step: %@\n", step.instructions);
        } // for each step in that route
    } // for each route
} // end method showRoute