All skills
mapbox avatar

/mapbox-flutter-patterns

@f6055fb official
by mapboxmapbox/mapbox-agent-skills80 stars
17

Official integration patterns for the Mapbox Maps Flutter SDK. Covers installation, iOS/Android platform setup, access token configuration, MapWidget initialization, camera control, annotations with tap handling, user location, and loading GeoJSON. Based on official Mapbox documentation.

Use this Skill: https://skilld.dev/gh/mapbox/mapbox-agent-skills/mapbox-flutter-patterns

This session only. Nothing lands on disk.

referencesplatform-setup.md

≈1.5k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Platform Setup: iOS, Android, Tokens

Deeper reference for getting mapbox_maps_flutter building and running cleanly on both platforms. The SKILL.md covers the 90% path — come here for details, gotchas, and CI/release notes.


iOS

Deployment target: 14.0

Mapbox requires iOS 14.0. Flutter's default is lower, which is why a fresh flutter create + flutter pub add mapbox_maps_flutter build fails.

Set the minimum deployment on the Runner target in Xcode (General → Minimum Deployments → iOS = 14.0). If the project has an ios/Podfile, update the platform line to match:

# ios/Podfile
platform :ios, '14.0'

After editing the Podfile, run:

cd ios && pod install && cd ..

If you get a Podfile.lock conflict, delete ios/Pods/, ios/Podfile.lock, and re-run pod install.

CocoaPods vs Swift Package Manager

The plugin ships both: ios/mapbox_maps_flutter.podspec (CocoaPods) and ios/mapbox_maps_flutter/Package.swift (SPM). Flutter decides which to use based on your app configuration — new projects on Flutter 3.29+ default to SPM, older projects stay on CocoaPods. Either works; you don't need to choose or vendor dependencies yourself.

To force a mode machine-wide:

flutter config --enable-swift-package-manager      # SPM
flutter config --no-enable-swift-package-manager   # CocoaPods only

Location permission

ios/Runner/Info.plist:

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

If you ever call any "Always" authorization API, you also need NSLocationAlwaysAndWhenInUseUsageDescription. Without the correct key, iOS will reject the permission prompt and CLLocationManager will stay in .notDetermined.

Background modes

The stock plugin does not require any background mode entitlement. Only enable Location updates under Signing & Capabilities → Background Modes if your app genuinely needs background location — each capability triggers additional App Store review scrutiny.

Apple Silicon simulator

No extra setup needed on Flutter 3.16+. If you see building for iOS Simulator, but linking in object file built for iOS, clean and re-run: flutter clean && cd ios && pod deintegrate && pod install.


Android

minSdk and compileSdk

// android/app/build.gradle.kts
android {
    defaultConfig {
        minSdk = 21
        targetSdk = 34
    }
    compileSdk = 34
}

The Mapbox Maven repository is configured automatically by the plugin; you do not need to add it yourself.

Permissions

android/app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

Android 10+ treats location as a runtime permission — use permission_handler or your own flow to request it before enabling the puck.

R8 / ProGuard

The SDK ships consumer ProGuard rules. No app-side configuration is required unless you've disabled consumer rules with android.proguardFiles.disableConsumer.

Platform view modes

Android has multiple platform-view hosting modes (TLHC_VD, TLHC_HC, HC, VD). The default is fine for most apps. If you see black frames during scroll, try switching MapWidget's androidHostingMode — this is an advanced knob, see the plugin's MapWidget docs.


Access tokens

Where it goes

const accessToken = String.fromEnvironment('ACCESS_TOKEN');

void main() {
  MapboxOptions.setAccessToken(accessToken);
  runApp(const MyApp());
}

Must run before any MapWidget is constructed — a token set later won't retroactively authenticate an already-created map.

Passing the token at build time

flutter run --dart-define=ACCESS_TOKEN=pk.your_public_token
flutter build ios --dart-define=ACCESS_TOKEN=$MAPBOX_TOKEN
flutter build apk --dart-define=ACCESS_TOKEN=$MAPBOX_TOKEN

For a team of developers, a --dart-define-from-file=env.json file (gitignored) is convenient:

// env.json
{ "ACCESS_TOKEN": "pk.your_public_token" }
flutter run --dart-define-from-file=env.json

Add env.json to .gitignore.

VS Code / Android Studio launch configs

.vscode/launch.json:

{
  "configurations": [
    {
      "name": "Flutter (dev)",
      "request": "launch",
      "type": "dart",
      "args": ["--dart-define-from-file=env.json"]
    }
  ]
}

Public vs secret tokens

Use a public token (pk.…) in the app — it's shipped in the binary and can be extracted. Rotate and scope it with URL restrictions in the Mapbox dashboard.

Secret tokens (sk.…) must never ship to the client; they are for server-side tile preprocessing, offline downloads in CI, etc.

Download token for installs

Some release workflows require a secret download token with the DOWNLOADS:READ scope. This is separate from the runtime public token and is not needed at app runtime — only by CI to fetch the native SDK binaries. If the Android build fails with "401 Unauthorized" fetching Mapbox artifacts, configure the download token in ~/.gradle/gradle.properties:

MAPBOX_DOWNLOADS_TOKEN=sk.your_downloads_token

CI notes

  • Cache the ~/.pub-cache, ios/Pods, and Gradle caches across runs — Flutter + Mapbox builds are slow from cold.
  • For iOS device builds, provision profiles must include the bundle ID; nothing Mapbox-specific.
  • Pass tokens via CI secrets, not committed files. Use --dart-define=ACCESS_TOKEN=${{ secrets.MAPBOX_PUBLIC_TOKEN }}.

Release checklist

  • ✅ iOS Runner Minimum Deployment = 14.0
  • ✅ Android minSdk = 21
  • ✅ Public token passed via --dart-define, not hard-coded
  • ✅ Location permission purpose strings in Info.plist
  • ✅ Location permissions declared in AndroidManifest.xml
  • ✅ MapboxOptions.setAccessToken(...) called in main() before runApp

Source: SKILL.md on GitHub

No alertstoday3 checks · Risk SAFE
  • Gen Agent Trust Hubtoday

    The skill provides official integration patterns for the Mapbox Maps Flutter SDK. It follows security best practices by recommending secure token management via build-time definitions and utilizing official Mapbox documentation and repositories. No malicious patterns or security vulnerabilities were identified.

  • Sockettoday

    No alerts

  • Snyktoday

    Risk: LOW · No issues

Signed by skilld at f6055fb. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 5 hours ago.

Activeupdated 3 days ago
  • mapbox
  • flutter
  • dart
  • maps
  • ios
  • android
  • geojson
  • annotations
  • location

README badge

README badge for mapbox/mapbox-agent-skills/mapbox-flutter-patterns

Provides official Mapbox Maps Flutter SDK integration patterns for iOS and Android, covering installation, access token setup, MapWidget initialization, annotations with tap handling, user location, and GeoJSON loading. Targets the mapbox_maps_flutter package with Dart and requires iOS 14.0+ deployment target.

Generated from the current SKILL.md.

Does this skill cover web or desktop Flutter apps?
No. The Mapbox Maps Flutter SDK targets iOS and Android only. Web and desktop are not supported.
What are the minimum iOS and Android versions required?
iOS deployment target must be 14.0 or higher. Android requires minSdk 21 or higher.
How do I handle access token configuration?
Call `MapboxOptions.setAccessToken(token)` in `main()` before creating any MapWidget. Pass the token via `--dart-define=ACCESS_TOKEN=pk.your_token` at build time, never hard-code it in source.
What is the current API for detecting taps on annotations?
Use `manager.tapEvents(onTap: ...)` on the annotation manager (PointAnnotationManager, CircleAnnotationManager, etc.). The older `addOnPointAnnotationClickListener` is deprecated.
Can I use annotations for thousands of features?
No. For large datasets, use a style layer with GeoJsonSource and SymbolLayer instead of creating individual annotations.

Generated from the current SKILL.md. These answers refresh after source changes.