Switch from Apple MapKit to the Mapbox iOS SDK

The Mapbox iOS SDK is our vector maps library for iOS. This guide is intended to help developers with Apple MapKit experience quickly move their apps to the Mapbox iOS SDK. Both Swift and Objective-C are supported below.

Heads up! We’re still actively developing the Mapbox iOS SDK and will update this guide as we improve its amazing features.

Getting started

Here’s what you’ll need to get started:

New to Mapbox and MapKit? You might want to start with our First steps with the Mapbox iOS SDK.

Initialize a map

In MapKit:

import MapKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        let mapView = MKMapView(frame: self.view.frame)

        view.addSubview(mapView)
    }
}
#import "ViewController.h"
#import <MapKit/MapKit.h>

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    MKMapView *mapView = [[MKMapView alloc] initWithFrame:self.view.frame];

    [self.view addSubview:mapView];
}

@end

In Mapbox:

import Mapbox

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        let mapView = MGLMapView(frame: view.bounds)

        view.addSubview(mapView)
    }
}
#import "ViewController.h"
#import <Mapbox/Mapbox.h>

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];

    [self.view addSubview:mapView];
}

@end

In Info.plist, set MGLMapboxAccessToken to your access token.

Changing map type/style

In MapKit:

mapView.mapType = .standard;

// available types:
//   .standard
//   .satellite
//   .hybrid
//   .satelliteFlyover (iOS 9)
//   .hybridFlyover (iOS 9)
mapView.mapType = MKMapTypeStandard;

// available types:
//   MKMapTypeStandard
//   MKMapTypeSatellite
//   MKMapTypeHybrid
//   MKMapTypeSatelliteFlyover (iOS 9)
//   MKMapTypeHybridFlyover (iOS 9)

In Mapbox:

mapView.styleURL = MGLStyle.lightStyleURL(9)

// available styles (see MGLStyle documentation):
//   streetsStyleURL(withVersion:)
//   outdoorsStyleURL(withVersion:)
//   lightStyleURL(withVersion:)
//   darkStyleURL(withVersion:)
//   satelliteStyleURL(withVersion:)
//   satelliteStreetsStyleURL(withVersion:)
mapView.styleURL = [MGLStyle lightStyleURLWithVersion:9];

// available styles (see MGLStyle documentation):
//   -streetsStyleURLWithVersion:
//   -outdoorsStyleURLWithVersion:
//   -lightStyleURLWithVersion
//   -darkStyleURLWithVersion:
//   -satelliteStyleURLWithVersion:
//   -satelliteStreetsStyleURLWithVersion:

To build your own styles, use Mapbox Studio.

Centering and zooming

In MapKit:

let zoomLevel = 15.0
let center = CLLocationCoordinate2D(latitude: 38.894368, longitude: -77.036487)
let span = MKCoordinateSpan(latitudeDelta: 0, longitudeDelta: (360 / (pow(2, zoomLevel)) * Double(mapView.frame.size.width / 256)))

let region = MKCoordinateRegion(center: center, span: span)
    
mapView.setRegion(region, animated: true)
double zoomLevel = 15;
CLLocationCoordinate2D centerCoordinate = CLLocationCoordinate2DMake(38.894368, -77.036487);

MKCoordinateRegion region = MKCoordinateRegionMake(centerCoordinate, MKCoordinateSpanMake(0, 360 / (pow(2, zoomLevel) * (mapView.frame.size.width / 256))));

[mapView setRegion:region animated:YES];

In Mapbox:

let center = CLLocationCoordinate2D(latitude: 38.894368, longitude: -77.036487)
mapView.setCenter(center, zoomLevel: 15, animated: true)
CLLocationCoordinate2D centerCoordinate = CLLocationCoordinate2DMake(38.894368, -77.036487);
[mapView setCenterCoordinate:centerCoordinate zoomLevel:15 animated:YES];

Bounding box fit

In MapKit, it’s a bit verbose to set a bounding box:

let sw = CLLocationCoordinate2D(latitude: 45.5087, longitude: -122.6903)
let ne = CLLocationCoordinate2D(latitude: 45.5245, longitude: -122.6503)

let swPoint = MKMapPointForCoordinate(sw)
let nePoint = MKMapPointForCoordinate(ne)

let swRect = MKMapRectMake(swPoint.x, swPoint.y, 0, 0)
let neRect = MKMapRectMake(nePoint.x, nePoint.y, 0, 0)

let mapRect = MKMapRectUnion(swRect, neRect)

mapView.setVisibleMapRect(mapRect, animated: false)
CLLocationCoordinate2D sw = CLLocationCoordinate2DMake(45.5087, -122.69);
CLLocationCoordinate2D ne = CLLocationCoordinate2DMake(45.5245, -122.65);

MKMapPoint swPoint = MKMapPointForCoordinate(sw);
MKMapPoint nePoint = MKMapPointForCoordinate(ne);

MKMapRect swRect = MKMapRectMake(swPoint.x, swPoint.y, 0, 0);
MKMapRect neRect = MKMapRectMake(nePoint.x, nePoint.y, 0, 0);

MKMapRect mapRect = MKMapRectUnion(swRect, neRect);

[mapView setVisibleMapRect:mapRect animated:NO];

In Mapbox:

// Set the map bounds to Portland, Oregon
let bounds = MGLCoordinateBounds(
    sw: CLLocationCoordinate2D(latitude: 45.5087, longitude: -122.69),
    ne: CLLocationCoordinate2D(latitude: 45.5245, longitude: -122.65))

mapView.setVisibleCoordinateBounds(bounds, animated: false)
// Set the map bounds to Portland, Oregon
CLLocationCoordinate2D sw = CLLocationCoordinate2DMake(45.5087, -122.69);
CLLocationCoordinate2D ne = CLLocationCoordinate2DMake(45.5245, -122.65);

[mapView setVisibleCoordinateBounds:MGLCoordinateBoundsMake(sw, ne) animated:NO];

Camera animation

In Apple Maps:

let coordinate = CLLocationCoordinate2DMake(35.5494, 139.77765)

let camera = MKMapCamera(lookingAtCenter: coordinate, fromDistance: 5000, pitch: 40, heading: 90)

mapView.setCamera(camera, animated: true)
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(35.5494, 139.77765);

MKMapCamera *camera = [MKMapCamera cameraLookingAtCenterCoordinate:coordinate
                                                      fromDistance:6000
                                                      pitch:40
                                                      heading:90];

[mapView setCamera:camera animated:YES];

In Mapbox:

let coordinate = CLLocationCoordinate2D(latitude: 35.5494, longitude: 139.77765)

let camera = MGLMapCamera(lookingAtCenter: coordinate, fromDistance: 5000, pitch: 40, heading: 90)

mapView.fly(to: camera, completionHandler: nil)
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(35.5494, 139.77765);

MGLMapCamera *camera = [MGLMapCamera cameraLookingAtCenterCoordinate:coordinate
                                                        fromDistance:5000
                                                        pitch:40
                                                        heading:90];

[mapView flyToCamera:camera completionHandler:nil];

Showing user location

In MapKit:

mapView.userTrackingMode = .follow

// available modes:
//   none
//   follow
//   followWithHeading
mapView.userTrackingMode = MKUserTrackingModeFollow;

// available modes:
//   MKUserTrackingModeNone
//   MKUserTrackingModeFollow
//   MKUserTrackingModeFollowWithHeading

In Mapbox:

mapView.userTrackingMode = .follow

// available modes:
//   none
//   follow
//   followWithHeading
//   followWithCourse
mapView.userTrackingMode = MGLUserTrackingModeFollow;

// available modes:
//   MGLUserTrackingModeNone
//   MGLUserTrackingModeFollow
//   MGLUserTrackingModeFollowWithHeading
//   MGLUserTrackingModeFollowWithCourse

Add pin/marker annotations

In MapKit:

class ViewController: UIViewController, MKMapViewDelegate {
    override func viewDidLoad() {
        ...

        mapView.delegate = self;
        
        let hello = MKPointAnnotation()
        hello.coordinate = CLLocationCoordinate2D(latitude: 40.717041, longitude: -73.988007)
        hello.title = "Hello world!"
        hello.subtitle = "Welcome to my marker"
        
        mapView.addAnnotation(hello)

    }

    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        
        let annotationView = MKPinAnnotationView()
        annotationView.pinTintColor = .purple
        
        return annotationView
    }
}
@interface ViewController () <MKMapViewDelegate>
@end

@implementation ViewController

- (void)viewDidLoad {
    ...

    mapView.delegate = self;

    MKPointAnnotation *hello = [[MKPointAnnotation alloc] init];
    hello.coordinate = CLLocationCoordinate2DMake(40.717041, -73.988007);
    hello.title = @"Hello world!";
    hello.subtitle = @"Welcome to my marker";

    [mapView addAnnotation:hello];
}

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
    // simple and inefficient example

    MKPinAnnotationView *annotationView = [[MKPinAnnotationView alloc] init];
    annotationView.pinColor = MKPinAnnotationColorPurple;

    return annotationView;
}

In Mapbox:

class ViewController: UIViewController, MGLMapViewDelegate {
    override func viewDidLoad() {
        ...

        // Set the delegate property of our map view to self after instantiating it.
        mapView.delegate = self
        
        // Declare the marker `hello` and set its coordinates, title, and subtitle.
        let hello = MGLPointAnnotation()
        hello.coordinate = CLLocationCoordinate2D(latitude: 40.717041, longitude: -73.988007)
        hello.title = "Hello world!"
        hello.subtitle = "Welcome to my marker"
        
        // Add marker `hello` to the map.
        mapView.addAnnotation(hello)
    }

    // Return `nil` here to use the default marker.
    func mapView(_ mapView: MGLMapView, viewFor annotation: MGLAnnotation) -> MGLAnnotationView? {
        return nil
    }

    // Allow callout view to appear when an annotation is tapped.
    func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
        return false
    }
}
@interface ViewController () <MGLMapViewDelegate>
@end

@implementation ViewController

- (void)viewDidLoad {
    ...

    // Set the delegate property of our map view to self after instantiating it.
    mapView.delegate = self;

    // Declare the marker `hello` and set its coordinates, title, and subtitle.
    MGLPointAnnotation *hello = [[MGLPointAnnotation alloc] init];
    hello.coordinate = CLLocationCoordinate2DMake(40.717041, -73.988007);
    hello.title = @"Hello world!";
    hello.subtitle = @"Welcome to my marker";

    // Add marker `hello` to the map.
    [mapView addAnnotation:hello];
}

// Return `nil` here to use the default marker.
- (MGLAnnotationView *)mapView:(MGLMapView *)mapView viewForAnnotation:(id <MGLAnnotation>)annotation {
    return nil;
}

// Allow callout view to appear when an annotation is tapped.
- (BOOL)mapView:(MGLMapView *)mapView annotationCanShowCallout:(id <MGLAnnotation>)annotation {
    return YES;
}

@end

Congratulations, you’ve mastered the basics of switching from MapKit. Check out all of the documentation for more features to try.

Have other comparisons between MapKit and Mapbox that you’d like to see? Get in touch!

Additional questions? Ask our support team or learn more about How Mapbox Works.