What is Mapbox?
Have you ever thought about building an application around navigation which allows users to explore places using proper maps? Today we’re going to set up and run “your own Google Maps” using Mapbox (just without Google).
What is Mapbox? It’s a group of services, SDKs and APIs for map building and navigation. We’ll check how to use “Mapbox Maps SDK for iOS” where the core of our interest is the map. Mapbox SDK is a flexible tool which allows you to choose the map data provider. You can let Mapbox do all the work in a subscription mode or provide OpenStreetMap (OSM) data from your server backend and have fully working setup for free. Here we’re going to take a simplistic approach and use Mapbox resource. It’s free to use until you reach a significant number of users (you can check details here).
Mapbox installation
The first steps process is fairly simple. The requirements here are: having Xcode installed on your system, minimum iOS development experience and a Mapbox account. It’s necessary to obtain a permission token to get access to their map source. It’s not needed when you provide map data.
Already have it? Ok, so let’s go!
For those already in the field, here we have some shortcut:
CocoaPods
Create a new file in project main folder, name it “podfile” (in terminal simply enter: “touch podfile”) and then add this:
1 2 3 |
target 'TargetNameForYourApp' do pod 'Mapbox-iOS-SDK', '~> 3.7' end |
Then run:
1 |
pod install |
Carthage
Add this to your Cartfile:
1 |
binary "https://www.mapbox.com/ios-sdk/Mapbox-iOS-SDK.json" ~> 3.7 |
Then run:
1 |
carthage update |
Standard “Carthage” – specific steps apply.
Download
A dead simple way is just to download “Mapbox.framework” file from:
https://www.mapbox.com/install/ios/download/
and follow the instructions there.
Make sure that you have “MGLMapboxAccessToken” entry in an info.plist file, with your personal access token. This authorizes your app to use Mapbox resources. You can find it at mapbox.com site. Just sign in and look for the “Access tokens” section.
Simple example
There are two ways of displaying a simple map example:
The first way:
- Go to your “Main.storyboard”
- Change top “View” class type to “MGLMapView”
- Having already selected “View”, set “Style URL” to “mapbox://styles/mapbox/streets-v10”
Still, the best way for customizing your map will be doing it from code.
Second way:
Add variable:
1 |
var mapView: MGLMapView! |
inside a view controller of your choice, then just add this code in viewDidLoad:
1 2 3 4 5 |
let url = URL(string: "mapbox://styles/mapbox/streets-v10") //URL to map resource mapView = MGLMapView(frame: view.bounds, styleURL: url) //main “map” class initialization mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight] //this makes sure that “mapView” takes whole available space in “superView” mapView.setCenter(CLLocationCoordinate2D(latitude: 52.06, longitude: 19.25), zoomLevel: 4, animated: false) //set geo coordinates here view.addSubview(mapView) //and finally add our map view to the actual already existing view. Notice that without this line, we would see just empty space |
Remember to add this line of code at top of file: import Mapbox.
Run and check if your map looks something like this:
Now we’re ready to move on to more interesting things.
Customizing and styling your map in Mapbox
User position
A first obvious step is to display the user position on our newly created map view.
Add this code at the end of viewDidLoad method and run the project again:
1 |
mapView.setUserTrackingMode(.follow, animated: true) |
The app crashed and you have got an exception? That’s because we didn’t ask the user for the permission when Mapbox was trying to get GPS position (so you don’t have to setup CLLocationManager and delegates, and all that stuff).
Go to an “Info.plist” file and add “NSLocationWhenInUseUsageDescription” key. For value, use whatever you like. I used “We need your location for displaying it on the map”. Always inform the user if you store location or use it for any other reason. Of course your app can be developed, but when dealing with the real project, it could be rejected during the AppStore review (keep that in mind). We could also use the option which allows access to the user location always, even when the app is in the background (but we won’t need it for our purposes).
When you run your app, you should get a system alert:
After authorisation a pointer on the map will indicate your current location:
Annotations
We often need to show something more than just the user’s position. Mapbox gives the annotation types for that. Annotation is a marker that can be placed on the map.
Add new method and call it at the end of “viewDidLoad”:
1 2 3 4 5 6 7 8 |
func addNewAnnotation() { let annotation = MGLPointAnnotation() annotation.coordinate = CLLocationCoordinate2D(latitude: 52.397519, longitude: 16.899333) annotation.title = "Appchance" annotation.subtitle = "Hello world!" mapView.addAnnotation(annotation) } |
Now your map shows point annotation, but what is there “title and “subtitle” for? To see the callout. By default, tapping on the marker does not trigger any action, because first we have to tell Mapbox to do so.
Write this line of code in – yep, you guessed – “viewDidLoad”:
1 |
mapView.delegate = self |
And at end of the file:
1 2 3 4 5 |
extension ViewController: MGLMapViewDelegate { func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool { return true } } |
The result is a simple pin on the map with callout and some text:
Conversions
MGLMapView provides some interesting methods, such as conversion from screen-space coordinates to geo coordinates and vice versa.

We can use it, for example, to allow the user to mark his favorite pizza restaurants or other points of interest. This is a pretty simple feature so let’s add this one to viewDidLoad:
1 2 |
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(longPressOnMap)) mapView.addGestureRecognizer(longPressRecognizer) |
And at end of the same file:
1 2 3 4 5 6 |
@objc func longPressOnMap(_ recognizer: UILongPressGestureRecognizer) { let longPressScreenCoordinates = recognizer.location(in: mapView) let longPressMapCoordinates = mapView.convert(longPressScreenCoordinates, toCoordinateFrom: mapView) addNewAnnotation(coordinates: longPressMapCoordinates) } |
Modify “addNewAnnotation” method to take a CLLocationCoordinate2D instance as an argument and run your project. You should see something like this:
Cameras
Camera in Mapbox is similar to the real world thing. It allows precise customization of users’ viewing position, height and angle. This is the “eye” through which map is visible. MGLMapView has always some default camera set and we used it even without knowing a bit about it. When we pan on the map, we change position of this default camera. Remember this line?
1 |
mapView.setCenter(CLLocationCoordinate2D(latitude: 52.06, longitude: 19.25), zoomLevel: 4, animated: false) |
This is just a convenient method for:
1 |
mapView.camera. //set different values here |
We can replace the default camera with our own, which can have very different properties. We can animate between cameras and chain animations with mapView.setCamera method and completion handlers.
Conclusion
I hope that this article has given you a glimpse into what you can do with Mapbox. You have learned how to install and run your first simple map, get user position, fill it with annotations and make a showcase to a user with a smooth animating camera. That’s a solid ground for your own projects.
See you next time and happy coding!
You might also like

Increasing mobile app retention focuses on the users returning…
Hi, please help me we are stuck in the recognize which one is longPressRecognizer and tabgesturerecognizer. Actually my requirement is that when i longpress at the mapbox than annotation appear(which one is fine) and when i tap at the map than remove the annotation.
Here is my code :
mapViewMapBox = [[MGLMapView alloc] initWithFrame:cell.contentView.bounds styleURL:url];
mapViewMapBox.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
mapViewMapBox.showsUserLocation = YES;
[self.mapview.ViewMapbox addSubview:mapViewMapBox];
[mapViewMapBox addGestureRecognizer:[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(mapLongPressed:)]];
//When i press long than the method called
– (void) mapLongPressed:(UILongPressGestureRecognizer*)sender
{
CGPoint point = [sender locationInView:mapViewMapBox];
CLLocationCoordinate2D coordinate = [mapViewMapBox convertPoint:point toCoordinateFromView:mapViewMapBox];
[self addMarkerNewAddress:coordinate map:mapViewMapBox ];
}
// Use Delegete method
– (void)mapView:(MGLMapView *)mapView didSelectAnnotation:(id )annotation{
}
If you want to remove annotation you can just use
[mapView removeAnnotation: annotation];
inside “didSelect annotation” delegate method.
I hope it helps 🙂
Thank you for the clear instructions. I’ve developed a simple map app using Mapbox (it shows an overlay of low stress bicycle routes around my city), 31 annotations with tips along the bike routes, and the users location. My app has been rejected by the Apple for lacking in content or features. The content is unique, base on 12 years of bicycling experience in my city. The features are minimal I suppose, but all I want to share is a simple map via app that I feel is much more convenient than a web page. Do you have any suggestions regarding enhanced features that Apple would like? Thanks for your consideration.
I have never encountered such problem before, but if I may suggest:
– incorporate gamification to your app, such as virtual points for distance travelled inside your app; later you could add virtual badges for achievements or other visual marks of app usage, maybe thats nothing but people like to show off and that could lead to rankings
– ability to add custom routes by users of your app (maybe someone knows city as good as you, or it could go viral to other cities where users also want to share their favorite routes)
– voting for best routes
– try creating some new views, such as settings (even if only for map pin image or map style), “About” page with some information or user profile page (data could be stored for now on device via UserDefaults or better CoreData/Realm database frameworks); features I mentioned above should populate your app with enough views
I think that should please Apple and let your app be published. I wish you best luck 🙂