mcpbeat Sign in

Mapbox Ios Patterns Agent Skill

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.

8k tokens
context cost
the whole folder, loaded on every use
8
files
instructions only
0
copies elsewhere
how many repositories repackaged it
51 d ago
last touched
this folder, not the whole repository

Install

one command, takes just this skill from the repository
npx skills add https://github.com/mapbox/mapbox-agent-skills --skill mapbox-ios-patterns

What comes with it

22 066 bytes besides the instruction
AGENTS.md
evals/evals.json
references/annotations.md
references/camera-styles.md
references/custom-data.md
references/interactions.md
references/location-tracking.md

The instruction itself

24 sections, as written by the author

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:


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:

<key>MBXAccessToken</key>
<string>pk.your_mapbox_token_here</string>

Get your token: Sign in at mapbox.com

Step 2: Add Swift Package Dependency

  • File → Add Package Dependencies
  • Enter URL: https://github.com/mapbox/mapbox-maps-ios.git
  • Version: "Up to Next Major" from 11.0.0
  • Verify four dependencies appear: MapboxCommon, MapboxCoreMaps, MapboxMaps, Turf

Alternative: CocoaPods or direct download (install guide)


Map Initialization

SwiftUI Pattern

Basic map:

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:

Map(viewport: $viewport)
    .mapStyle(.standard)
    .ornamentOptions(OrnamentOptions(
        scaleBar: .init(visibility: .visible),
        compass: .init(visibility: .adaptive),
        logo: .init(position: .bottomLeading)
    ))

UIKit Pattern

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.

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:

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:

Map(viewport: $viewport) {
    PointAnnotation(coordinate: CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194))
        .image(.init(image: UIImage(named: "marker")!, name: "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 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:

<key>NSLocationWhenInUseUsageDescription</key>
<string>Show your location on the map</string>

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:

  • MBXAccessToken in Info.plist
  • ✅ Token is valid (test at mapbox.com)
  • ✅ MapboxMaps framework imported
  • ✅ MapView added to view hierarchy
  • ✅ 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

  • 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

Other skills for the same job

different authors, same section of the catalogue
MCP Builder
by anthropics
vendor ×13

Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).

30k tokens scripts
Changelog Generator
by frostant
×9

Automatically creates user-facing changelogs from git commits by analyzing commit history, categorizing changes, and transforming technical commits into clear, customer-friendly release notes. Turns hours of manual changelog writing into minutes of automated generation.

774 tokens
Finishing A Development Branch
by ZhanlinCui
×7

Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for merge, PR, or cleanup

1k tokens
MCP Builder
by JayZeeDesign
×7

Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).

37k tokens scripts
Vercel React Native Skills
by vercel-labs
vendor ×6

React Native and Expo best practices for building performant mobile apps. Use when building React Native components, optimizing list performance, implementing animations, or working with native modules. Triggers on tasks involving React Native, Expo, mobile performance, or native platform APIs.

39k tokens
Vercel React Best Practices
by ratacat
×5

React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.

34k tokens
Next Best Practices
by vercel-labs
vendor ×4

Next.js best practices - file conventions, RSC boundaries, data patterns, async APIs, metadata, error handling, route handlers, image/font optimization, bundling

20k tokens
Using Git Worktrees
by ZhanlinCui
×4

Use when starting feature work that needs isolation from current workspace or before executing implementation plans - creates isolated git worktrees with smart directory selection and safety verification

1k tokens

How to use it

Copy the folder

Take mapbox/mapbox-ios-patterns from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

The agent identifies a skill by the name field in its header. Two skills with the same name cannot sit side by side — one of them will be ignored.