mapbox-ios-patterns
Integrates Mapbox Maps SDK v11 on iOS using Swift and SwiftUI, enabling map display, marker placement, user location tracking, and custom data rendering.
Identity proven by GitHub's verified organisation badge (mapbox)
- Agents
- Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode, claude.ai and API
- License
- MIT (permissive)
- Pin
- f71cd72pinned Oct 9, 2026
- Context cost
- about 2,600 tokenswhen the skill loads
- GitHub stars
- 80on mapbox/mapbox-agent-skills
- Scripts
- None found
What it does
“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.”
Generated summary from the skill's own text
Integrates Mapbox Maps SDK v11 on iOS using Swift and SwiftUI, enabling map display, marker placement, user location tracking, and custom data rendering. Provides patterns for installation, annotation management, style control, and feature interactions based on official Mapbox documentation.
When to use it
- Building iOS map applications with markers and user tracking
- Adding GeoJSON features and custom styles to maps
- Implementing location-based features in SwiftUI or UIKit
- Handling map gestures, taps, and feature interactions
When not to
- Targeting iOS versions below 14 or Xcode below 15
- Displaying thousands of markers without using style layers
- Web-based or Android map implementations
Install
These commands install from the publisher's repository and need no account.
skills CLI
npx skills add mapbox/mapbox-agent-skills --skill mapbox-ios-patternsInstalls from the repository's default branch, which may have changed since the commit we checked.
GitHub CLI 2.90 or later
gh skill install mapbox/mapbox-agent-skills mapbox-ios-patterns@f71cd72b8d8937b06db440538bd65559eb792c49Installs the commit we checked (f71cd72).
Copy by hand
Download the folder at f71cd72 and put it in .claude/skills/mapbox-ios-patterns for Claude Code and in .agents/skills/mapbox-ios-patterns for Codex, Cursor, Gemini CLI, GitHub Copilot and OpenCode.
Claude Code plugin
/plugin install mapbox@claude-plugins-officialThe publisher's plugin in Claude's official marketplace. It may hold more than this skill, and we have not pinned it.
Copy for your agent
A prompt for any coding agent. It installs this skill from GitHub at the pinned commit, copies the files as they are, and runs nothing unless you ask.
Prompt
Install the agent skill "mapbox-ios-patterns" by Mapbox. Source, pinned to commit f71cd72b8d8937b06db440538bd65559eb792c49: https://github.com/mapbox/mapbox-agent-skills/tree/f71cd72b8d8937b06db440538bd65559eb792c49/skills/mapbox-ios-patterns 1. Download that folder at exactly this commit. Do not use the default branch. 2. Copy every file unchanged, keeping the folder structure, into .claude/skills/mapbox-ios-patterns/ for Claude Code and .agents/skills/mapbox-ios-patterns/ for Codex, Cursor, Gemini CLI, GitHub Copilot and OpenCode. Create the folders if they do not exist. 3. Do not edit the files, and do not run any script in the folder unless I ask you to. 4. When you are done, list the files you copied and where you put them. Listing and checks: https://www.agentnative.dev/skills/mapbox/mapbox-ios-patterns
SKILL.md at the pin
---
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:**
- Installing and configuring Mapbox Maps SDK for iOS
- Adding markers and annotations to maps
- Showing user location and tracking with camera
- Adding custom data (GeoJSON) to maps
- Working with map styles, camera, or user interaction
- Handling feature interactions and taps
**Official Resources:**
- [iOS Maps Guides](https://docs.mapbox.com/ios/maps/guides/)
- [API Reference](https://docs.mapbox.com/ios/maps/api-reference/)
- [Example Apps](https://github.com/mapbox/mapbox-maps-ios/tree/main/Sources/Examples)
---
## Installation & Setup
### Requirements
- iOS 14+
- Xcode 15+
- Swift 5.9+
- Free Mapbox account
### Step 1: Configure Access Token
Add your public token to `Info.plist`:
```xml
<key>MBXAccessToken</key>
<string>pk.your_mapbox_token_here</string>
```
**Get your token:** Sign in at [mapbox.com](https://account.mapbox.com/access-tokens/)
### 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](https://docs.mapbox.com/ios/maps/guides/install/))
---
## Map Initialization
### SwiftUI Pattern
**Basic map:**
```swift
import SwiftUI
import MapboxMaps
struct 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:**
```swift
Map(viewport: $viewport)
.mapStyle(.standard)
.ornamentOptions(OrnamentOptions(
scaleBar: .init(visibility: .visible),
compass: .init(visibility: .adaptive),
logo: .init(position: .bottomLeading)
))
```
### UIKit Pattern
```swift
import UIKit
import MapboxMaps
class 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
The SDK offers three ways to place a point on the map. Pick the simplest one that fits.
**Agent note:** A SwiftUI Mapbox sketch is incomplete without at least one annotation (`Marker`, `PointAnnotation`, or `MapViewAnnotation`). Do not ship a bare `Map { }` with no pin.
### Which API should I use?
| API | Use it when | Platforms | Notes |
| --------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Marker` (Markers API) | You need a default pin and don't have a custom image asset | SwiftUI only | No image assets required. Experimental SPI — needs `@_spi(Experimental) import MapboxMaps`. Best < 100 markers. |
| `PointAnnotation` | You have a custom image and want layer-level placement | SwiftUI + UIKit | Backed by a symbol layer, so it scales well to hundreds of markers. Accepts any `UIImage` that `UIKit` can render. |
| View annotations (`ViewAnnotation` / `MapViewAnnotation`) | You want to render a full native view (card, badge, animated content) anchored to a coordinate | SwiftUI + UIKit | SwiftUI uses `MapViewAnnotation`; UIKit uses `mapView.viewAnnotations` with a `ViewAnnotation`. Each annotation is a real view — costs more than `PointAnnotation` at scale. |
For hundreds or thousands of features, use a style layer (`SymbolLayer` on a `GeoJSONSource`) instead of annotations.
### Markers API (recommended for simple cases, SwiftUI)
```swift
import SwiftUI
@_spi(Experimental) import MapboxMaps
struct ContentView: View {
var body: some View {
Map {
Marker(coordinate: CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194))
.color(.red)
.text("San Francisco")
}
}
}
```
Multiple markers from a collection:
```swift
Map {
ForEvery(locations, id: \.id) { location in
Marker(coordinate: location.coordinate)
.color(.red)
.text(location.name)
}
}
```
> **Scaling note.** `Marker` and `PointAnnotation` each create their own view or symbol entry per pin — fine up to about 100 markers. For larger datasets (hundreds or thousands of features — common with open-ended GeoJSON feeds), load the data into a `GeoJSONSource` and render it with a `SymbolLayer` instead. That scales to thousands of features and enables clustering.
### PointAnnotation (custom image)
**SwiftUI:**
```swift
Map(viewport: $viewport) {
PointAnnotation(coordinate: CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194))
.image(.init(image: UIImage(named: "marker")!, name: "marker"))
}
```
**UIKit:**
```swift
// 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:**
```swift
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:**
```xml
<key>NSLocationWhenInUseUsageDescription</key>
<string>Show your location on the map</string>
```
**Step 2: Request permissions and show location:**
```swift
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
```swift
// ❌ 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
```swift
// ✅ Update all at once
pointAnnotationManager.annotations = newAnnotations
// ❌ Don't update one by one
for annotation in newAnnotations {
pointAnnotationManager.annotations.append(annotation)
}
```
### Memory Management
```swift
// 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
```swift
// ✅ 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
```swift
mapView.mapboxMap.onStyleLoaded.observe { [weak self] _ in
print("Style loaded successfully")
// Add layers and sources here
}.store(in: &cancelables)
```
### Performance Issues
- Use `.standard` style (recommended and optimized)
- Limit visible annotations to viewport
- Reuse annotation managers
- Avoid frequent style reloads
- Batch annotation updates
---
## Reference Files
Load these references when the task requires deeper patterns:
- **`references/annotations.md`** — Circle, Polyline, Polygon Annotations
- **`references/location-tracking.md`** — Camera Follow User + Get Current Location
- **`references/custom-data.md`** — GeoJSON: Lines, Polygons, Points, Update/Remove
- **`references/camera-styles.md`** — Camera Control + Map Styles
- **`references/interactions.md`** — Featureset Interactions, Custom Layer Taps, Long Press, Gestures
---
## Additional Resources
- [iOS Maps Guides](https://docs.mapbox.com/ios/maps/guides/)
- [API Reference](https://docs.mapbox.com/ios/maps/api/11.18.1/documentation/mapboxmaps/)
- [Interactions Guide](https://docs.mapbox.com/ios/maps/guides/user-interaction/Interactions/)
- [SwiftUI User Guide](https://docs.mapbox.com/ios/maps/api/11.18.1/documentation/mapboxmaps/swiftui-user-guide)
- [Example Apps](https://github.com/mapbox/mapbox-maps-ios/tree/main/Sources/Examples)
- [Migration Guide (v10 → v11)](https://docs.mapbox.com/ios/maps/guides/migrate-to-v11/)
From mapbox/mapbox-agent-skills at f71cd72, shown as plain text under its license: MIT (permissive). The license text is in LICENSE.md.
View SKILL.md on GitHub at f71cd72Files
- SKILL.md11 KB · 82112821943d
- AGENTS.md6.3 KB · 47d9bc42f624
- evals/
- evals.json2.6 KB · 4d673e793f2d
- references/
- annotations.md3.2 KB · fc90682cce7a
- camera-styles.md2.0 KB · 987a53892b51
- custom-data.md2.7 KB · 02ad926402cd
- interactions.md3.7 KB · cb51e126a04f
- location-tracking.md1.7 KB · 8fd73740b141
8 files, 33 KB in total. Each file has a sha256 in the pin's manifest; the first 12 characters are shown.
Skill folder on GitHub at f71cd72More from Mapbox
mapbox-android-patterns
This skill provides official patterns for integrating Mapbox Maps SDK v11 on Android, covering setup, map initialization, markers, user location display…
Claude Code, Codex, Cursor +4 · about 2.5K tokens · pinned 6 days ago
mapbox-cartography
This skill provides cartographic expertise for designing effective maps with Mapbox, covering visual hierarchy, color theory, typography, and zoom strategies.
Claude Code, Codex, Cursor +4 · about 1.7K tokens · pinned 6 days ago
mapbox-data-visualization-patterns
This skill teaches the agent to implement data visualization patterns on Mapbox maps, including choropleth maps, heat maps, 3D extrusions, and animated data…
Claude Code, Codex, Cursor +4 · about 2.1K tokens · pinned 6 days ago
mapbox-flutter-patterns
This skill teaches agents the standard patterns for integrating the Mapbox Maps Flutter SDK into iOS and Android apps written in Dart.
Claude Code, Codex, Cursor +4 · about 2.3K tokens · pinned 6 days ago
mapbox-geospatial-operations
This skill guides agents on selecting appropriate geospatial tools from the Mapbox MCP Server based on problem requirements.
Claude Code, Codex, Cursor +4 · about 4.8K tokens · pinned 6 days ago
mapbox-google-maps-migration
This skill guides developers migrating from Google Maps Platform to Mapbox GL JS by comparing APIs, translating patterns, and highlighting architectural…
Claude Code, Codex, Cursor +4 · about 2.9K tokens · pinned 6 days ago
Related in Mobile
figma-swiftui
This skill translates between Figma designs and SwiftUI code in both directions.
by FigmaOfficial publisher
Claude Code · about 830 tokens · pinned 6 days ago
apollo-ios
This skill guides building GraphQL-powered Apple apps with Apollo iOS, a strongly-typed Swift client.
by Apollo GraphQLOfficial publisher
Contains scripts
Claude Code · about 1.8K tokens · pinned 6 days ago
expo-app-intents
This skill adds Apple App Intents to Expo apps, enabling Siri voice commands and Shortcuts automation through Swift declarations that dispatch to JavaScript…
by ExpoOfficial publisher
Claude Code, Codex, Cursor +4 · about 3.6K tokens · pinned 6 days ago
expo-brownfield
This skill helps agents add React Native to existing native iOS or Android apps incrementally using Expo.
by ExpoOfficial publisher
Claude Code, Codex, Cursor +4 · about 1.4K tokens · pinned 6 days ago
expo-migrate-module
Converts the Swift source code of an existing Expo native module from the 1.0 definition DSL to the 2.0 macro API, keeping its JavaScript and TypeScript…
by ExpoOfficial publisher
Claude Code, Codex, Cursor +3 · about 2.5K tokens · pinned 6 days ago
expo-module
This skill guides agents through creating and writing Expo native modules and views using the Expo Modules API with Swift, Kotlin, and TypeScript.
by ExpoOfficial publisher
Claude Code, Codex, Cursor +3 · about 1.5K tokens · pinned 6 days ago