There are plenty of resources on how to acquire driving directions between two points or addresses. Examples are Google Maps Driving Directions API or Apples MKDirections.

What is generally returned from these API:s are some form of polyline that can be drawn on a map along with “steps” of driving directions, e.g. “Take a right”, “Take a left” etc.

It is not clear however how to display these instructions in realtime without user interaction. That is why we developed NavigationKit — a drop-in library for getting driving directions and then displaying these steps with Turn-by-Turn directions that automatically updates when the user drives and recalculates the route when the user takes a wrong turn.

NavigationKit is available on our GitHub: http://github.com/sendus/NavigationKit

The repository contains an example project that you can install on a device and try in your car.

How does it work?

Step 1. Initialise NavigationKit by supplying:

1. Source Coordinates

2. Destination Coordinates

3. Transportation type (defaults to MKDirectionsTransportTypeAutoMobile)

4. Directions service, a choice between Apple or Google (I prefer Google)

self.navigationKit = [[NavigationKit alloc] initWithSource:CLLocationCoordinate2DMake(40.7056258, -73.97968) destination:CLLocationCoordinate2DMake(40.7720805, -73.5385279) transportType:MKDirectionsTransportTypeAutomobile directionsService:NavigationKitDirectionsServiceGoogleMaps]; [navigationKit setDelegate:self];

Step 2. Calculate Directions

[self.navigationKit calculateDirections];

Step 3. Respond to Delegate methods

When NavigationKit found a route it will invoke a delegate method called

- (void)navigationKitCalculatedRoute:(NKRoute *)route { }

This is a perfect place to display the routes polyline on a map and perhaps start navigating. In order for NavigationKit to calculate actions it needs continous location data. Use CLLocationManager for this and send in new locations as soon as you get them:

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { CLLocation *location = [locations firstObject]; [self.navigationKit calculateActionForLocation:location]; }

When this is done NavigationKit will continuously invoke delegate methods to notify the user of new steps and actions that should be undertaken as well as a new camera angle that can be updated in the map.

- (void)navigationKitEnteredRouteStep:(NKRouteStep *)step nextStep:(NKRouteStep *)nextStep {

// We entered a new step, display the next step instructions to the user

} - (void)navigationKitCalculatedNotificationForStep:(NKRouteStep *)step inDistance:(CLLocationDistance)distance {

// Notify the user about an important notification, e.g. via Speech Synthesising

} - (void)navigationKitCalculatedCamera:(MKMapCamera *)camera {

[self.mapView setCamera:camera animated:YES];

}

Why?

It is a very neat experience for a user to never leave a native application instead of being thrown out to Google or Apple Maps when driving directions needs to be shown. For some users it can also be quite confusing when trying to return to the original application.

Caveats

So I made this in a week.

It is obviously not near as good as Google Maps or Apple Maps Turn-by-Turn navigation, they have a bit more manpower than we do. That is why we open-sourced this. Hopefully you are a developer that finds this interesting and can submit improvements. Feel free to fork the project on GitHub!

One of the major caveats is that neither Apple Maps or Google Maps supports returning driving directions while taking a current heading into consideration. This means that sometimes when you drive, the driving directions would tell you to drive backwards into traffic, and then continue to recalculate the route until you entered another street. I am uncertain if this can be fixed in NavigationKit rather than at API level.

Who am I?

My name is Axel Moller, and I am an iOS developer and Scrum Master.

I work for a tech Startup in Stockholm called budbee. We excel in same-day deliveries for e-commerce by integrating into webshops and Transport Administration-systems and then optimising the routes with our proprietary route optimisation algorithm. Speed and optimisation is key for us, thus the decision to develop our own Turn-by-Turn navigation instead of forcing users out to Google Maps.

You can find NavigationKit here: http://github.com/sendus/NavigationKit