apple-corelocation について
apple-corelocationは、AppleプラットフォームでCoreLocationを使う開発者向けのプログラミング資料スキルです。位置情報更新、権限、ジオフェンス、ジオコーディング、バックグラウンド更新を扱い、iOS 17以降の非同期APIも説明します。
主な機能
- 01iOS 17以降の非同期位置情報パターン
- 02認証と権限設定の説明
- 03領域監視とジオコーディング
- 04バックグラウンド位置情報と電力管理
- 05CoreLocationの主要API一覧
活用シーン
- 01SwiftUIアプリで位置情報をリアルタイム取得
- 02位置情報の権限と状態変化を処理
- 03ジオフェンスや住所変換を設定
- 04バックグラウンド更新の電力消費を抑制
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ ios-agent/ iosagent.dev --skill apple-corelocationインストール後、Claude Code で/apple-corelocationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/authorization.mdbackground.mdbeacon-compass.mdgeocoding.mdlive-updates.mdlocation-manager.mdmonitoring.md詳細
Apple CoreLocation スキル
正確でモダンな CoreLocation コードを書くには、このスキルを使用してください。CoreLocation は、地理的位置、高度、方位、iBeacon への近接性に関するサービスを提供します。 Wi-Fi、GPS、Bluetooth、磁力計、気圧計、携帯電話通信のハードウェアを利用します。
リファレンスファイルを読むタイミング
この SKILL.md には、基本的なパターンと API のクイックリファレンスが記載されています。 実装の詳細を確認するには、適切なリファレンスファイルを読んでください。
| トピック | リファレンスファイル | 読むタイミング |
|---|---|---|
| ライブ更新と async/await のパターン | references/live-updates.md | SwiftUI アプリ、非同期の位置情報ストリーム、バックグラウンドアクティビティセッション |
| 認証と権限 | references/authorization.md | 権限のフロー、Info.plist のキー、認証ステータスの処理 |
| リージョン監視と CLMonitor | references/monitoring.md | ジオフェンシング、条件監視、円形リージョン |
| ジオコーディング | references/geocoding.md | 住所 ↔ 座標の変換、逆ジオコーディング、CLPlacemark |
| iBeacon とコンパス | references/beacon-compass.md | ビーコンの距離測定、方位の更新、磁力計 |
| バックグラウンド位置情報 | references/background.md | バックグラウンド更新、CLBackgroundActivitySession、電力の最適化 |
| CLLocationManager API | references/location-manager.md | CLLocationManager のプロパティとメソッドの完全なリファレンス |
モダンな 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?— 位置情報。取得できない場合は nilisStationary: 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 の主なプロパティ
| プロパティ | 型 | 説明 |
|---|---|---|
coordinate | CLLocationCoordinate2D | 緯度と経度(WGS 84) |
altitude | CLLocationDistance | 海抜高度(メートル) |
horizontalAccuracy | CLLocationAccuracy | 精度(メートル単位。負の値は無効) |
verticalAccuracy | CLLocationAccuracy | 高度の精度(メートル単位) |
speed | CLLocationSpeed | 速度(メートル毎秒) |
course | CLLocationDirection | 真北を基準とした角度 |
timestamp | Date | 位置が特定された日時 |
floor | CLFloor? | 建物の階数(利用可能な場合) |
sourceInformation | CLLocationSourceInformation? | 位置情報のソースに関する情報 |
電力を最適化するためのガイドライン
ユースケースに応じて、最も電力効率の高いサービスを選んでください。
-
訪問サービス(
startMonitoringVisits()) — 最も電力効率が高く、訪問した場所と滞在時間を報告します。用途の例:チェックインアプリ、旅行記録。 -
重要な変更の監視サービス(
startMonitoringSignificantLocationChanges()) — 消費電力が少なく、Wi-Fi/携帯電話ネットワークのみを使用します。用途の例:おおよその位置追跡。 -
標準位置情報サービス(
startUpdatingLocation()) —desiredAccuracyで精度を設定できます。用途の例:ナビゲーション、フィットネスの追跡。 -
ライブアップデート(
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も設定してください。