Mapbox iOS Patterns
by @mapbox
Official integration patterns for Mapbox Maps SDK on iOS. Covers installation, adding markers, user location, custom data, styles, camera control, and featur...
clawhub install mapbox-ios-patternsπ About This Skill
name: mapbox-ios-patterns description: Official integration patterns for Mapbox Maps SDK on iOS. Covers installation, adding markers, user location, custom data, styles, camera control, and featureset interactions. Based on official Mapbox documentation.
Mapbox iOS Integration Patterns
Official patterns for integrating Mapbox Maps SDK v11 on iOS with Swift, SwiftUI, and UIKit.
Use this skill when:
Official Resources:
Installation & Setup
Requirements
Step 1: Configure Access Token
Add your public token to Info.plist:
MBXAccessToken
pk.your_mapbox_token_here
Get your token: Sign in at mapbox.com
Step 2: Add Swift Package Dependency
1. File β Add Package Dependencies
2. Enter URL: https://github.com/mapbox/mapbox-maps-ios.git
3. Version: "Up to Next Major" from 11.0.0
4. Verify four dependencies appear: MapboxCommon, MapboxCoreMaps, MapboxMaps, Turf
Alternative: CocoaPods or direct download (install guide)
Map Initialization
SwiftUI Pattern (iOS 13+)
Basic map:
import SwiftUI
import MapboxMapsstruct ContentView: View {
@State private var viewport: Viewport = .camera(
center: CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194),
zoom: 12
)
var body: some View {
Map(viewport: $viewport)
.mapStyle(.standard)
}
}
With ornaments:
Map(viewport: $viewport)
.mapStyle(.standard)
.ornamentOptions(OrnamentOptions(
scaleBar: .init(visibility: .visible),
compass: .init(visibility: .adaptive),
logo: .init(position: .bottomLeading)
))
UIKit Pattern
import UIKit
import MapboxMapsclass MapViewController: UIViewController {
private var mapView: MapView!
override func viewDidLoad() {
super.viewDidLoad()
let options = MapInitOptions(
cameraOptions: CameraOptions(
center: CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194),
zoom: 12
)
)
mapView = MapView(frame: view.bounds, mapInitOptions: options)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(mapView)
mapView.mapboxMap.loadStyle(.standard)
}
}
Add Markers (Point Annotations)
Point annotations are the most common way to mark locations on the map.
SwiftUI:
Map(viewport: $viewport) {
PointAnnotation(coordinate: CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194))
.iconImage("custom-marker")
}
UIKit:
// Create annotation manager (once, reuse for updates)
var pointAnnotationManager = mapView.annotations.makePointAnnotationManager()// Create marker
var annotation = PointAnnotation(coordinate: CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194))
annotation.image = .init(image: UIImage(named: "marker")!, name: "marker")
annotation.iconAnchor = .bottom
// Add to map
pointAnnotationManager.annotations = [annotation]
Multiple markers:
let locations = [
CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194),
CLLocationCoordinate2D(latitude: 37.7849, longitude: -122.4094),
CLLocationCoordinate2D(latitude: 37.7649, longitude: -122.4294)
]let annotations = locations.map { coordinate in
var annotation = PointAnnotation(coordinate: coordinate)
annotation.image = .init(image: UIImage(named: "marker")!, name: "marker")
return annotation
}
pointAnnotationManager.annotations = annotations
Show User Location
Step 1: Add location permission to Info.plist:
NSLocationWhenInUseUsageDescription
Show your location on the map
Step 2: Request permissions and show location:
import CoreLocation// Request permissions
let locationManager = CLLocationManager()
locationManager.requestWhenInUseAuthorization()
// Show user location puck
mapView.location.options.puckType = .puck2D()
mapView.location.options.puckBearingEnabled = true
Performance Best Practices
Reuse Annotation Managers
// β Don't create new managers repeatedly
func updateMarkers() {
let manager = mapView.annotations.makePointAnnotationManager()
manager.annotations = markers
}// β
Create once, reuse
let pointAnnotationManager: PointAnnotationManager
init() {
pointAnnotationManager = mapView.annotations.makePointAnnotationManager()
}
func updateMarkers() {
pointAnnotationManager.annotations = markers
}
Batch Annotation Updates
// β
Update all at once
pointAnnotationManager.annotations = newAnnotations// β Don't update one by one
for annotation in newAnnotations {
pointAnnotationManager.annotations.append(annotation)
}
Memory Management
// Use weak self in closures
mapView.gestures.onMapTap.observe { [weak self] context in
self?.handleTap(context.coordinate)
}.store(in: &cancelables)// Clean up on deinit
deinit {
cancelables.forEach { $0.cancel() }
}
Use Standard Style
// β
Standard style is optimized and recommended
.mapStyle(.standard)// Use other styles only when needed for specific use cases
.mapStyle(.standardSatellite) // Satellite imagery
Troubleshooting
Map Not Displaying
Check:
1. β
MBXAccessToken in Info.plist
2. β
Token is valid (test at mapbox.com)
3. β
MapboxMaps framework imported
4. β
MapView added to view hierarchy
5. β
Correct frame/constraints set
Style Not Loading
mapView.mapboxMap.onStyleLoaded.observe { [weak self] _ in
print("Style loaded successfully")
// Add layers and sources here
}.store(in: &cancelables)
Performance Issues
.standard style (recommended and optimized)Reference Files
Load these references when the task requires deeper patterns:
references/annotations.md β Circle, Polyline, Polygon Annotationsreferences/location-tracking.md β Camera Follow User + Get Current Locationreferences/custom-data.md β GeoJSON: Lines, Polygons, Points, Update/Removereferences/camera-styles.md β Camera Control + Map Stylesreferences/interactions.md β Featureset Interactions, Custom Layer Taps, Long Press, GesturesAdditional Resources
π Tips & Best Practices
Map Not Displaying
Check:
1. β
MBXAccessToken in Info.plist
2. β
Token is valid (test at mapbox.com)
3. β
MapboxMaps framework imported
4. β
MapView added to view hierarchy
5. β
Correct frame/constraints set
Style Not Loading
mapView.mapboxMap.onStyleLoaded.observe { [weak self] _ in
print("Style loaded successfully")
// Add layers and sources here
}.store(in: &cancelables)
Performance Issues
.standard style (recommended and optimized)