mcpField
A
apple-corelocation

apple-corelocation

github.com/ios-agent開発1255 回インストール34 週間前に更新
リポジトリ

apple-corelocation について

apple-corelocationは、AppleプラットフォームでCoreLocationを使う開発者向けのプログラミング資料スキルです。位置情報更新、権限、ジオフェンス、ジオコーディング、バックグラウンド更新を扱い、iOS 17以降の非同期APIも説明します。

主な機能

  1. 01iOS 17以降の非同期位置情報パターン
  2. 02認証と権限設定の説明
  3. 03領域監視とジオコーディング
  4. 04バックグラウンド位置情報と電力管理
  5. 05CoreLocationの主要API一覧

活用シーン

  1. 01SwiftUIアプリで位置情報をリアルタイム取得
  2. 02位置情報の権限と状態変化を処理
  3. 03ジオフェンスや住所変換を設定
  4. 04バックグラウンド更新の電力消費を抑制

インストール

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

$npx skills add https://github.com/ios-agent/iosagent.dev --skill apple-corelocation

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

同梱ファイル

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

references/
authorization.md
background.md
beacon-compass.md
geocoding.md
live-updates.md
location-manager.md
monitoring.md

詳細

Apple CoreLocation スキル

正確でモダンな CoreLocation コードを書くには、このスキルを使用してください。CoreLocation は、地理的位置、高度、方位、iBeacon への近接性に関するサービスを提供します。 Wi-Fi、GPS、Bluetooth、磁力計、気圧計、携帯電話通信のハードウェアを利用します。

リファレンスファイルを読むタイミング

この SKILL.md には、基本的なパターンと API のクイックリファレンスが記載されています。 実装の詳細を確認するには、適切なリファレンスファイルを読んでください。

トピックリファレンスファイル読むタイミング
ライブ更新と async/await のパターンreferences/live-updates.mdSwiftUI アプリ、非同期の位置情報ストリーム、バックグラウンドアクティビティセッション
認証と権限references/authorization.md権限のフロー、Info.plist のキー、認証ステータスの処理
リージョン監視と CLMonitorreferences/monitoring.mdジオフェンシング、条件監視、円形リージョン
ジオコーディングreferences/geocoding.md住所 ↔ 座標の変換、逆ジオコーディング、CLPlacemark
iBeacon とコンパスreferences/beacon-compass.mdビーコンの距離測定、方位の更新、磁力計
バックグラウンド位置情報references/background.mdバックグラウンド更新、CLBackgroundActivitySession、電力の最適化
CLLocationManager APIreferences/location-manager.mdCLLocationManager のプロパティとメソッドの完全なリファレンス

モダンな CoreLocation(iOS 17 以降):async/await を優先

iOS 17 以降、CoreLocation は Swift の並行処理をサポートしています。新規プロジェクトでは、従来のデリゲートベースの方法より、モダンな非同期 API を優先してください。

ライブ位置情報更新の取得(推奨パターン)
import CoreLocation

let updates = CLLocationUpdate.liveUpdates()

for try await update in updates {
    if let location = update.location {
        // Process location
        print("Lat: \(location.coordinate.latitude), Lon: \(location.coordinate.longitude)")
    }
    if update.authorizationDenied {
        // Handle denied authorization
    }
    if update.authorizationRequestInProgress {
        // System is showing the authorization dialog
    }
}

ステータスが .notDetermined の場合、反復処理の開始時にシステムが自動的に認証を求めます。このパターンでは、明示的に requestWhenInUseAuthorization() を呼び出す必要はありませんが、タイミングを制御するために呼び出すこともできます。

精度を設定したライブ更新
// High accuracy (GPS, more power)
let updates = CLLocationUpdate.liveUpdates(.default)

// Power-efficient options
let updates = CLLocationUpdate.liveUpdates(.automotiveNavigation)
let updates = CLLocationUpdate.liveUpdates(.otherNavigation)
let updates = CLLocationUpdate.liveUpdates(.fitness)
let updates = CLLocationUpdate.liveUpdates(.airborne)
CLLocationUpdate のプロパティ
  • location: CLLocation? — 位置情報。取得できない場合は nil
  • isStationary: Bool — デバイスが静止しているかどうか
  • authorizationDenied: Bool — 認証が拒否されたかどうか
  • authorizationDeniedGlobally: Bool — 位置情報サービスがシステム全体で無効になっているかどうか
  • authorizationRequestInProgress: Bool — 認証ダイアログが表示中かどうか
  • insufficientlyInUse: Bool — アプリの「使用中」状態が不十分かどうか
  • locationUnavailable: Bool — 位置情報が一時的に利用できないかどうか
  • accuracyLimited: Bool — 精度に関する認証が制限されているかどうか

SwiftUI 統合パターン

@MainActor
class LocationsHandler: ObservableObject {
    static let shared = LocationsHandler()
    private let manager: CLLocationManager
    private var background: CLBackgroundActivitySession?

    @Published var lastLocation = CLLocation()
    @Published var isStationary = false

    @Published var updatesStarted: Bool = UserDefaults.standard.bool(forKey: "liveUpdatesStarted") {
        didSet { UserDefaults.standard.set(updatesStarted, forKey: "liveUpdatesStarted") }
    }

    private init() {
        self.manager = CLLocationManager()
    }

    func startLocationUpdates() {
        if self.manager.authorizationStatus == .notDetermined {
            self.manager.requestWhenInUseAuthorization()
        }
        Task {
            do {
                self.updatesStarted = true
                let updates = CLLocationUpdate.liveUpdates()
                for try await update in updates {
                    if !self.updatesStarted { break }
                    if let loc = update.location {
                        self.lastLocation = loc
                        self.isStationary = update.isStationary
                    }
                }
            } catch {
                print("Could not start location updates")
            }
        }
    }

    func stopLocationUpdates() {
        self.updatesStarted = false
    }
}

認証クイックリファレンス

Info.plist のキー(必須)
キー使用する場面
NSLocationWhenInUseUsageDescriptionアプリがフォアグラウンドで位置情報を使用する場合
NSLocationAlwaysAndWhenInUseUsageDescriptionアプリがバックグラウンドでも位置情報を必要とする場合
NSLocationDefaultAccuracyReducedデフォルトで精度を下げて要求する場合
認証ステータスの値(CLAuthorizationStatus)
値意味
.notDeterminedユーザーにまだ確認していません
.restrictedアプリは位置情報を使用できません(例:ペアレンタルコントロール)
.deniedユーザーが明示的に拒否しました
.authorizedWhenInUseアプリはフォアグラウンドで位置情報を使用できます
.authorizedAlwaysアプリはいつでも位置情報を使用できます
認証の要求
let manager = CLLocationManager()

// For foreground-only access
manager.requestWhenInUseAuthorization()

// For background access (after getting "When In Use" first)
manager.requestAlwaysAuthorization()

// For temporary full accuracy (when user granted reduced accuracy)
manager.requestTemporaryFullAccuracyAuthorization(withPurposeKey: "MyPurposeKey")

CLMonitor による条件監視(iOS 17 以降)

let monitor = await CLMonitor("myMonitor")

// Add a circular geographic condition
await monitor.add(
    CLMonitor.CircularGeographicCondition(center: coordinate, radius: 200),
    identifier: "coffee-shop"
)

// Observe events
for try await event in await monitor.events {
    switch event.state {
    case .satisfied:
        print("Entered region: \(event.identifier)")
    case .unsatisfied:
        print("Exited region: \(event.identifier)")
    default:
        break
    }
}

ジオコーディングのクイックリファレンス

let geocoder = CLGeocoder()

// Reverse geocode: coordinate → address
geocoder.reverseGeocodeLocation(location) { placemarks, error in
    if let placemark = placemarks?.first {
        print(placemark.locality ?? "Unknown city")
    }
}

// Forward geocode: address → coordinate
geocoder.geocodeAddressString("1 Apple Park Way, Cupertino") { placemarks, error in
    if let location = placemarks?.first?.location {
        print(location.coordinate)
    }
}

CLLocation の主なプロパティ

プロパティ型説明
coordinateCLLocationCoordinate2D緯度と経度(WGS 84)
altitudeCLLocationDistance海抜高度(メートル)
horizontalAccuracyCLLocationAccuracy精度(メートル単位。負の値は無効)
verticalAccuracyCLLocationAccuracy高度の精度(メートル単位)
speedCLLocationSpeed速度(メートル毎秒)
courseCLLocationDirection真北を基準とした角度
timestampDate位置が特定された日時
floorCLFloor?建物の階数(利用可能な場合)
sourceInformationCLLocationSourceInformation?位置情報のソースに関する情報

電力を最適化するためのガイドライン

ユースケースに応じて、最も電力効率の高いサービスを選んでください。

  1. 訪問サービス(startMonitoringVisits()) — 最も電力効率が高く、訪問した場所と滞在時間を報告します。用途の例:チェックインアプリ、旅行記録。

  2. 重要な変更の監視サービス(startMonitoringSignificantLocationChanges()) — 消費電力が少なく、Wi-Fi/携帯電話ネットワークのみを使用します。用途の例:おおよその位置追跡。

  3. 標準位置情報サービス(startUpdatingLocation()) — desiredAccuracy で精度を設定できます。用途の例:ナビゲーション、フィットネスの追跡。

  4. ライブアップデート(CLLocationUpdate.liveUpdates()) — アクティビティタイプを設定できる最新の非同期 API です。用途の例:iOS 17 以降を対象とする新規プロジェクト全般。

希望する精度の定数
定数説明
kCLLocationAccuracyBestForNavigation最高精度で、消費電力も最大
kCLLocationAccuracyBest利用可能な最高精度
kCLLocationAccuracyNearestTenMeters約 10 メートル以内
kCLLocationAccuracyHundredMeters約 100 メートル以内
kCLLocationAccuracyKilometer約 1 km 以内
kCLLocationAccuracyThreeKilometers約 3 km 以内
kCLLocationAccuracyReduced意図的に精度を低下

プラットフォームに関する考慮事項

  • visionOS:位置情報サービスには制限があります。バックグラウンドでの更新はサポートされていません。 visionOS で動作する互換性のある iPad/iPhone アプリでは、リージョン監視メソッドは何も行いません。
  • macOS:アプリはバックグラウンドで一時停止されないため、特別なバックグラウンド機能は必要ありません。
  • watchOS:機能を有効にすると、バックグラウンドでの位置情報取得をサポートします。CLBackgroundActivitySession を使用してください。
  • ウィジェット:ウィジェットの利用可否は isAuthorizedForWidgetUpdates で確認してください。

よくある落とし穴

  • 必ず horizontalAccuracy を確認してください。負の値は座標が無効であることを意味します。
  • サービスの開始後、位置情報がすぐに利用可能になるとは限りません。
  • 認証状態の変更を適切に処理してください。ユーザーは「設定」からいつでも許可を取り消せます。
  • ジオコーダーへのリクエストにはレート制限があります。結果をキャッシュし、位置情報が更新されるたびにジオコードしないでください。
  • システムは位置情報の更新を自動的に一時停止することがあります。pausesLocationUpdatesAutomatically と activityType を設定すると、CoreLocation が適切に判断できるようになります。
  • iOS でバックグラウンド更新を行うには、「Location updates」バックグラウンドモード機能を追加し、 ロケーションマネージャーで allowsBackgroundLocationUpdates = true も設定してください。

コメント