mcpField
M
mapbox-ios-patterns

mapbox-ios-patterns

github.com/mapbox開発831.5k 回インストール4 週間前に更新
リポジトリ

mapbox-ios-patterns について

Swift、SwiftUI、UIKitで地図アプリを開発するiOS開発者向けに、Mapbox Maps SDK v11の連携パターンをまとめたスキルです。地図の初期化、注釈、位置表示、独自データ、操作に加え、性能とトラブルシューティングも扱います。

主な機能

  1. 01SwiftUIとUIKitでの地図初期化
  2. 02マーカーと注釈の追加
  3. 03ユーザー位置表示とカメラ追従
  4. 04GeoJSON独自データの読み込み
  5. 05地図スタイルと操作の処理
  6. 06注釈の性能とライフサイクルの指針

活用シーン

  1. 01iOSアプリへのMapbox地図の組み込み
  2. 02場所を示す独自マーカーの追加
  3. 03地図上でのユーザー位置の表示
  4. 04地図上の要素タップやジェスチャーの処理

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mapbox/mapbox-agent-skills --skill mapbox-ios-patterns

インストール後、Claude Code で/mapbox-ios-patternsを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

AGENTS.md
evals/
evals.json
references/
annotations.md
camera-styles.md
custom-data.md
interactions.md
location-tracking.md

詳細

Mapbox iOS 統合パターン

Swift、SwiftUI、UIKit を使用して、iOS で Mapbox Maps SDK v11 を統合するための公式パターンです。

次の用途でこのスキルを使用します:

  • Mapbox Maps SDK for iOS のインストールと設定
  • 地図へのマーカーとアノテーションの追加
  • ユーザーの位置の表示とカメラによる追跡
  • カスタムデータ(GeoJSON)の地図への追加
  • 地図のスタイル、カメラ、ユーザー操作の処理
  • フィーチャーの操作とタップの処理

公式リソース:


インストールとセットアップ

要件
  • iOS 14+
  • Xcode 15+
  • Swift 5.9+
  • 無料の Mapbox アカウント
手順 1:アクセストークンを設定する

公開トークンを Info.plist に追加します:

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

トークンの取得: mapbox.com にサインインします。

手順 2:Swift Package の依存関係を追加する
  1. File → Add Package Dependencies
  2. URL を入力: https://github.com/mapbox/mapbox-maps-ios.git
  3. バージョン: 11.0.0 から「Up to Next Major」を選択します
  4. 確認: MapboxCommon、MapboxCoreMaps、MapboxMaps、Turf の 4 つの依存関係が表示されることを確認します

代替方法: CocoaPods または直接ダウンロード(インストールガイド)


地図の初期化

SwiftUI パターン

基本的な地図:

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)
    }
}

オーナメント付き:

Map(viewport: $viewport)
    .mapStyle(.standard)
    .ornamentOptions(OrnamentOptions(
        scaleBar: .init(visibility: .visible),
        compass: .init(visibility: .adaptive),
        logo: .init(position: .bottomLeading)
    ))
UIKit パターン
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)
    }
}

マーカーを追加する

SDK には、地図上にポイントを配置する方法が 3 つあります。用途に合った、最もシンプルな方法を選んでください。

エージェント向けの注意: SwiftUI の Mapbox スケッチには、少なくとも 1 つのアノテーション(Marker、PointAnnotation、または MapViewAnnotation)が必要です。ピンのない Map { } をそのまま出荷しないでください。

どの API を使えばよいですか?
API使用する状況プラットフォーム備考
Marker(Markers API)デフォルトのピンが必要で、カスタム画像アセットがない場合SwiftUI のみ画像アセットは不要です。Experimental SPI のため、@_spi(Experimental) import MapboxMaps が必要です。100 個未満のマーカーに最適です。
PointAnnotationカスタム画像があり、レイヤーレベルで配置したい場合SwiftUI + UIKitシンボルレイヤーをベースにしているため、数百個のマーカーにも適切に対応できます。UIKit が描画できる任意の UIImage を受け付けます。
ビューアノテーション(ViewAnnotation / MapViewAnnotation)座標に固定した完全なネイティブビュー(カード、バッジ、アニメーションコンテンツ)を表示したい場合SwiftUI + UIKitSwiftUI では MapViewAnnotation を使用し、UIKit では ViewAnnotation とともに mapView.viewAnnotations を使用します。各アノテーションは実際のビューであり、大規模な場合は PointAnnotation よりコストがかかります。

数百から数千のフィーチャーには、アノテーションではなくスタイルレイヤー(GeoJSONSource 上の SymbolLayer)を使用してください。

Markers API(シンプルなケースに推奨、SwiftUI)
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")
        }
    }
}

コレクションから複数のマーカーを表示する場合:

Map {
    ForEvery(locations, id: \.id) { location in
        Marker(coordinate: location.coordinate)
            .color(.red)
            .text(location.name)
    }
}

スケーリングに関する注意。 Marker と PointAnnotation はそれぞれ、ピンごとに独自のビューまたはシンボルエントリーを作成します。マーカーが約100個までであれば問題ありません。より大きなデータセット(数百または数千のフィーチャー。オープンエンドなGeoJSONフィードでは一般的です)では、データを GeoJSONSource に読み込み、代わりに SymbolLayer で描画してください。これにより、数千のフィーチャーに対応でき、クラスタリングも有効になります。

PointAnnotation(カスタム画像)

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]

複数のマーカー:

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

ユーザーの位置を表示する

手順1:Info.plist に位置情報の使用許可を追加します:

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

手順2:使用許可をリクエストして位置情報を表示します:

import CoreLocation

// Request permissions
let locationManager = CLLocationManager()
locationManager.requestWhenInUseAuthorization()

// Show user location puck
mapView.location.options.puckType = .puck2D()
mapView.location.options.puckBearingEnabled = true

パフォーマンスに関するベストプラクティス

Annotation Manager を再利用する
// ❌ 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
}
アノテーションの更新をバッチ処理する
// ✅ Update all at once
pointAnnotationManager.annotations = newAnnotations

// ❌ Don't update one by one
for annotation in newAnnotations {
    pointAnnotationManager.annotations.append(annotation)
}
メモリ管理
// 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() }
}
標準スタイルを使用する
// ✅ Standard style is optimized and recommended
.mapStyle(.standard)

// Use other styles only when needed for specific use cases
.mapStyle(.standardSatellite) // Satellite imagery

トラブルシューティング

マップが表示されない

確認項目:

  1. ✅ Info.plist の MBXAccessToken
  2. ✅ トークンが有効であること(mapbox.com でテストしてください)
  3. ✅ MapboxMaps フレームワークがインポートされていること
  4. ✅ MapView がビュー階層に追加されていること
  5. ✅ 正しいフレーム/制約が設定されていること
スタイルが読み込まれない
mapView.mapboxMap.onStyleLoaded.observe { [weak self] _ in
    print("Style loaded successfully")
    // Add layers and sources here
}.store(in: &cancelables)
パフォーマンスの問題
  • .standard スタイルを使用します(推奨されており、最適化されています)
  • ビューポート内に表示するアノテーションの数を制限します
  • Annotation Manager を再利用します
  • スタイルの頻繁な再読み込みを避けます
  • アノテーションの更新をバッチ処理します

参考ファイル

より詳しいパターンが必要なタスクでは、以下のリファレンスを読み込んでください:

  • references/annotations.md — Circle、Polyline、Polygon のアノテーション
  • references/location-tracking.md — カメラでユーザーを追跡する方法 + 現在地の取得
  • references/custom-data.md — GeoJSON:ライン、ポリゴン、ポイント、更新/削除
  • references/camera-styles.md — カメラ制御 + マップスタイル
  • references/interactions.md — フィーチャーセットとのインタラクション、カスタムレイヤーのタップ、長押し、ジェスチャー

その他のリソース

コメント