Mapbox SDK integration in mobile app

NOVASOLUTIONS.TECHNOLOGY is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
Mapbox SDK integration in mobile app
Medium
from 1 business day to 3 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1052
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

Mapbox SDK Integration into a Mobile Application

Mapbox is the choice when you need full control over the visual style of your map: custom colors, fonts, layer hiding, and adding your own data sources on top of the base map. Mapbox GL / Mapbox Maps SDK v11 work with vector tiles and render the map natively through Metal (iOS) or OpenGL ES / Vulkan (Android) — hence the smooth rotation and zoom without pixelization.

Versioning: v10 vs v11

Mapbox Maps SDK for Android v11 (2023+) and iOS v11 are essentially a new SDK with a different API compared to v9/v10. Key changes: MapboxMap instead of MapboxMapOptions, ViewAnnotation instead of custom MarkerView, PointAnnotationManager instead of SymbolManager. If you find examples with addMarker() — that's v9, not applicable.

Integration

Android:

// settings.gradle
dependencyResolutionManagement {
    repositories {
        maven {
            url = uri("https://api.mapbox.com/downloads/v2/releases/maven")
            authentication { create<BasicAuthentication>("basic") }
            credentials {
                username = "mapbox"
                password = providers.gradleProperty("MAPBOX_DOWNLOADS_TOKEN").get()
            }
        }
    }
}

// build.gradle (app)
implementation("com.mapbox.maps:android:11.7.0")

The download token (MAPBOX_DOWNLOADS_TOKEN) is separate from the public access token. Both are required.

iOS (SPM):

// In Xcode: File → Add Package Dependencies
// URL: https://github.com/mapbox/mapbox-maps-ios
// Version: 11.x

Access token is set in Info.plist with the key MBXAccessToken or programmatically:

MapboxOptions.accessToken = "pk.eyJ1IjoiLi4uIn0..."

Basic Map with Custom Style

import MapboxMaps

class MapViewController: UIViewController {
    var mapView: MapView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let cameraOptions = CameraOptions(
            center: CLLocationCoordinate2D(latitude: 55.7558, longitude: 37.6173),
            zoom: 12
        )

        let initOptions = MapInitOptions(
            cameraOptions: cameraOptions,
            styleURI: StyleURI(rawValue: "mapbox://styles/your-username/your-style-id")
            // or StyleURI.streets / .dark / .satellite
        )

        mapView = MapView(frame: view.bounds, mapInitOptions: initOptions)
        mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view.addSubview(mapView)
    }
}

Styles are created in Mapbox Studio — a web editor with full control over each layer. Changes in Studio are published instantly without updating the application.

PointAnnotationManager: Markers in v11

mapView.mapboxMap.onMapLoaded.observeNext { [weak self] _ in
    guard let self else { return }

    var annotationManager = self.mapView.annotations.makePointAnnotationManager()
    var annotations = [PointAnnotation]()

    let points: [(Double, Double, String)] = [
        (55.7558, 37.6173, "Center"),
        (55.7518, 37.6105, "Arbat")
    ]

    for (lat, lng, title) in points {
        var annotation = PointAnnotation(
            coordinate: CLLocationCoordinate2D(latitude: lat, longitude: lng)
        )
        annotation.image = .init(image: UIImage(named: "custom-pin")!, name: "custom-pin")
        annotation.iconSize = 1.0
        annotation.textField = title
        annotation.textOffset = [0, 2]
        annotations.append(annotation)
    }

    annotationManager.annotations = annotations
    annotationManager.annotationInteractionDelegate = self
}

Android: Adding a GeoJSON Layer

Mapbox allows you to add your own GeoJSON as a data source and render it via a style — this is more powerful than markers for a large number of points:

mapView.mapboxMap.loadStyle(Style.MAPBOX_STREETS) { style ->
    // Add source
    style.addSource(
        GeoJsonSource.Builder("locations-source")
            .data("""
                {
                  "type": "FeatureCollection",
                  "features": [
                    { "type": "Feature",
                      "geometry": { "type": "Point", "coordinates": [37.6173, 55.7558] },
                      "properties": { "name": "Point A" }
                    }
                  ]
                }
            """.trimIndent())
            .build()
    )

    // Add symbol layer
    style.addLayer(
        SymbolLayer("locations-layer", "locations-source").apply {
            iconImage("custom-icon")
            iconSize(1.0)
            textField(get("name"))
            textOffset(listOf(0.0, 1.5))
        }
    )
}

For 10,000+ points, this is the only performant approach — PointAnnotationManager with thousands of objects begins to degrade FPS.

Offline Maps

val offlineManager = OfflineManager()
val tileStore = TileStore.create()

val tilesetDescriptor = offlineManager.createTilesetDescriptor(
    TilesetDescriptorOptions.Builder()
        .styleURI(Style.MAPBOX_STREETS)
        .minZoom(10)
        .maxZoom(16)
        .build()
)

val tileRegionLoadOptions = TileRegionLoadOptions.Builder()
    .geometry(Point.fromLngLat(37.6173, 55.7558)) // or Polygon for area
    .descriptors(listOf(tilesetDescriptor))
    .build()

tileStore.loadTileRegion("moscow-center", tileRegionLoadOptions, { progress ->
    Log.d("Mapbox", "Downloaded: ${progress.completedResourceCount}/${progress.requiredResourceCount}")
}, { result ->
    result.fold({ region -> Log.d("Mapbox", "Done: ${region.id}") }, { error -> })
})

Timeline

1–3 days. Basic map with custom style — 1 day. GeoJSON layers, offline, clustering — 2–3 days. Cost is calculated individually.