Xamarin iOS 7 MapKit MKDirections

Greetings! In the post we’ll cover using the MKDirections class to retrieve direction related information from Apple. We’ll then use those directions to draw a route on the map. The source code can be found on GitHub

First, we need the following namespaces

using MonoTouch.MapKit;
using MonoTouch.CoreLocation;

Next, we’ll add an MKMapView instance variable, and a MPMapViewDelegate.

        private MKMapView _map;
        private MKMapViewDelegate _mapDelegate;

In the ViewController’s ViewDidLoad method we will initialize the map, the map delegate, and call a method to get directions and create a route.

        public override void ViewDidLoad()        {
            base.ViewDidLoad();

            //Init Map
            _map = new MKMapView
            {
                MapType = MKMapType.Standard,
                ShowsUserLocation = true,
                ZoomEnabled = true,
                ScrollEnabled = true
            };

            //Create new MapDelegate Instance
            _mapDelegate = new MapDelegate();

            //Add delegate to map
            _map.Delegate = _mapDelegate;

            View = _map;

            //Create Directions
            CreateRoute();
        }

The CreateRoute function is where the magic happens…

We’ll need to crate two MKPlaceMarks, one for the source and one for the destination. These are used to create two MKMapItems that are used when making the directions request.

            //Create Origin and Dest Place Marks and Map Items to use for directions
            //Start at Xamarin SF Office
            var orignPlaceMark = new MKPlacemark(new CLLocationCoordinate2D(37.797530, -122.402590), null);
            var sourceItem = new MKMapItem(orignPlaceMark);

            //End at Xamarin Cambridge Office
            var destPlaceMark = new MKPlacemark(new CLLocationCoordinate2D(42.374172, -71.120639), null);
            var destItem = new MKMapItem(destPlaceMark);

Next, we’ll need to create a request for directions using MKDirectionsRequest using the the source and dest items above, and pass these to a new instance of MKDirections.

            var request = new MKDirectionsRequest
            {
                Source = sourceItem,
                Destination = destItem,
                RequestsAlternateRoutes = true
            };

            var directions = new MKDirections(request);

Next, we need to make the call to get the directions. When the directions are returned, we’ll loop through the collections of routes and add the PolyLine from each route to our map overlay collection.

            directions.CalculateDirections((response, error) =>
            {
                if (error != null)
                {
                    Console.WriteLine(error.LocalizedDescription);
                }
                else
                {
                   //Add each Polyline from route to map as overlay
                    foreach (var route in response.Routes)
                    {
                        _map.AddOverlay(route.Polyline);
                    }
                }
            });

Remember the _mapDelegate we create earlier? This is actually a class that inherits from MKMapViewDelegate. We need to override the OverlayRenderer in order to actually draw the route on the map.

  class MapDelegate : MKMapViewDelegate
  {
        //Override OverLayRenderer to draw Polyline from directions
        public override MKOverlayRenderer OverlayRenderer(MKMapView mapView, IMKOverlay overlay)
            {
                if (overlay is MKPolyline)
                {
                    var route = (MKPolyline)overlay;
                    var renderer = new MKPolylineRenderer(route) { StrokeColor = UIColor.Blue };
                    return renderer;
                }
                return null;
            }
        }

    }

That’s it! When we put it all together we end up with the map below.

iOS 7 Directions

iOS 7 Directions

About these ads

31 thoughts on “Xamarin iOS 7 MapKit MKDirections

  1. Thanks. Its a nice tutorial.
    I am using MKDirectionsRequest in my app to draw route between two points. But i am getting error as a response. Error message : “Directions not available”. I am trying to find route between pune to mumbai.

    Do i have to do some initial settings before using MKDirections request ?

    Can you please help me regarding the same.

    Thanks in advance.

    • Thanks for the reply. I tried getting directions using Apple’s map program and received the same error. It looks like Apple hasn’t added support for that route just yet. You might try contacting Apple to get an ETA on when they plan to add this in.

      Regards,
      Blake

      • David thanks a lot for the reply.
        So its like they haven’t added route support for all locations. Can you please tell me which locations are route supported?
        How can i support turn by turn navigation in ios7 app?

      • Himani, althought this post is from last year, it looks like Apple Maps hasn’t added support for India still…

        It looks like your best bet is to use google maps.

        The easiest way for you to implement true turn-by-turn directions is to launch google maps using an Url scheme.

        If displaying the directions within your app is a requirement, I could post an example on retrieving directions/displaying route using google maps directions API, but it would be up to you to figure out the turn-by-turn piece.

        -Blake

      • I am working on Apple map component so i dont want to use Google Map API to display route between two locations.
        I have gone through the MKDirections Class documentation ,as per my understanding it is possible to show route and turn by turn navigation with MapKit Framework in ios7.
        As it is newly released not much information is available in internet.
        Can you please help me out regarding the same.

        Can you please help me out regarding the same. If

      • Could you please show me where in the MKDirections Class documentation it states that Turn-by-turn navigation is available? I’m fairly familiar with the class myself, but only found where you can get directions, not fully functioning turn by turn navigation. As I stated earlier, the directions service is not available for India, so if you’re looking to get your app going soon, google maps appears to be your only option. I apologize that I can’t offer much more help than this.

        -Blake

      • steps property of MKRoute Class would do for turn by turn navigation. Please correct me if i have misunderstood.
        Thanks for your time and help.

  2. Hi Blake !

    Thanks for the link you shared in your last post. It really helped me.

    Looking into the other new features of ios7,i am facing difficulty in implementing 3D view for my map.

    I have set the altitude and pitch but still i am unable to implement 3D view.

    If you are familiar with this concept can you please help me out.

      • Hi Blake :) !
        I followed the Larry O’ Brien post for 3D view, but it was not working. I don’t know what is the problem. I can’t see the 3D buildings as it was shown in the screenshot ( Larry’s Post ).

      • Himani, Sorry for taking so long to get back to you. I was out of town for the weekend. I tested the code below, and it appears to dispaly 3D maps, however it only works on an actual device!

        public class MyViewController : UIViewController
        {
        private MKMapView _mapView;

        public MyViewController()
        {
        }

        public override void ViewDidLoad()
        {
        base.ViewDidLoad();

        _mapView = new MKMapView(View.Bounds);

        var target = new CLLocationCoordinate2D(37.7952, -122.4028);
        var viewPoint = new CLLocationCoordinate2D(37.8009, -122.4100);

        //Enable 3D buildings
        _mapView.ShowsBuildings = true;
        _mapView.PitchEnabled = true;

        var camera = MKMapCamera.CameraLookingAtCenterCoordinate(target, viewPoint, 500);
        _mapView.Camera = camera;
        View = _mapView;
        }
        }

        -Blake

  3. Pingback: Programmatic Apple Maps – Can and Can’ts » Xamarin Developments | Xamarin Developments

  4. Pingback: Programmatic Apple Maps – Cans and Cants » Xamarin Developments | Xamarin Developments

  5. Hi really it wondering.. but when I use your sample I am getting this error

    Objective-C exception thrown. Name: NSInvalidArgumentException Reason: -[MKDirectionsRequest setRequestsAlternateRoutes:]: unrecognized selector sent to instance 0×16935880

    Pleas you help me to solve this.

  6. Ok Thanks . I have another doubt Davidsonblake. If I use iOS7 in my app and if my user device is lower version mean, how can I handle ?

    • You’ll want to do a check of the users platform, and handle it appropriately. Depending on your app you might notify the user that the feature is only available for ios7 and later.

    • That’s completely up to you and your client to decide. Obviously you don’t want to try and execute iOS 7 only APIs on an iOS 6 device. As I suggested earlier you might display an alert. If the feature is available for both operating systems, but handled a bit differently you can perform your (see screen capture), you can perform your check and execute the correct code accordingly.

      Blake

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s