apple-corelocation
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseApple CoreLocation Skill
Apple CoreLocation 参考技能
Use this skill to write correct, modern CoreLocation code. CoreLocation provides
services for geographic location, altitude, orientation, and proximity to iBeacons.
It uses Wi-Fi, GPS, Bluetooth, magnetometer, barometer, and cellular hardware.
使用此技能编写规范、现代化的CoreLocation代码。CoreLocation提供地理位置、海拔、方向以及与iBeacon的距离检测服务,它会使用Wi-Fi、GPS、蓝牙、磁力计、气压计和蜂窝网络硬件。
When to Read Reference Files
何时阅读参考文档
This SKILL.md contains the essential patterns and quick-reference API surface.
For deeper implementation details, read the appropriate reference file:
| Topic | Reference File | When to Read |
|---|---|---|
| Live Updates & async/await patterns | | SwiftUI apps, async location streams, background activity sessions |
| Authorization & Permissions | | Permission flows, Info.plist keys, authorization status handling |
| Region Monitoring & CLMonitor | | Geofencing, condition monitoring, circular regions |
| Geocoding | | Address ↔ coordinate conversion, reverse geocoding, CLPlacemark |
| iBeacon & Compass | | Beacon ranging, heading updates, magnetometer |
| Background Location | | Background updates, CLBackgroundActivitySession, power optimization |
| CLLocationManager API | | Full property/method reference for CLLocationManager |
本SKILL.md包含核心使用模式和快速参考的API概览。如需更深入的实现细节,请阅读对应的参考文档:
| 主题 | 参考文档 | 阅读场景 |
|---|---|---|
| 实时更新与async/await模式 | | SwiftUI应用、异步位置流、后台活动会话 |
| 授权与权限 | | 权限流程、Info.plist键、授权状态处理 |
| 区域监控与CLMonitor | | 地理围栏、条件监控、圆形区域 |
| 地理编码 | | 地址↔坐标转换、逆地理编码、CLPlacemark |
| iBeacon与罗盘 | | 信标测距、航向更新、磁力计 |
| 后台位置 | | 后台更新、CLBackgroundActivitySession、功耗优化 |
| CLLocationManager API | | CLLocationManager的完整属性/方法参考 |
Modern CoreLocation (iOS 17+): Prefer Async/Await
现代化CoreLocation(iOS 17+):优先使用Async/Await
Since iOS 17, CoreLocation supports Swift concurrency. Prefer the modern async API
over the legacy delegate-based approach for new projects.
自iOS 17起,CoreLocation支持Swift并发。对于新项目,优先使用现代化的异步API,而非传统的基于代理的方式。
Getting Live Location Updates (Recommended Pattern)
获取实时位置更新(推荐模式)
swift
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
}
}The system automatically prompts for authorization when iteration begins if
status is . No explicit call
is needed with this pattern, but you may still call it for controlled timing.
.notDeterminedrequestWhenInUseAuthorization()swift
import CoreLocation
let updates = CLLocationUpdate.liveUpdates()
for try await update in updates {
if let location = update.location {
// 处理位置信息
print("纬度: \(location.coordinate.latitude), 经度: \(location.coordinate.longitude)")
}
if update.authorizationDenied {
// 处理授权被拒绝的情况
}
if update.authorizationRequestInProgress {
// 系统正在显示授权对话框
}
}如果授权状态为,当开始迭代时系统会自动提示用户授权。使用此模式无需显式调用,但你也可以主动调用以控制时机。
.notDeterminedrequestWhenInUseAuthorization()Live Updates with Accuracy Configuration
带精度配置的实时更新
swift
// 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)swift
// 高精度(GPS,功耗较高)
let updates = CLLocationUpdate.liveUpdates(.default)
// 低功耗选项
let updates = CLLocationUpdate.liveUpdates(.automotiveNavigation)
let updates = CLLocationUpdate.liveUpdates(.otherNavigation)
let updates = CLLocationUpdate.liveUpdates(.fitness)
let updates = CLLocationUpdate.liveUpdates(.airborne)CLLocationUpdate Properties
CLLocationUpdate 属性
- — The location, or nil if unavailable
location: CLLocation? - — Whether the device is stationary
isStationary: Bool - — Authorization was denied
authorizationDenied: Bool - — Location services disabled system-wide
authorizationDeniedGlobally: Bool - — Auth dialog is being shown
authorizationRequestInProgress: Bool - — App lacks sufficient "in use" state
insufficientlyInUse: Bool - — Location data temporarily unavailable
locationUnavailable: Bool - — Accuracy authorization is reduced
accuracyLimited: Bool
- — 位置信息,不可用时为nil
location: CLLocation? - — 设备是否处于静止状态
isStationary: Bool - — 授权已被拒绝
authorizationDenied: Bool - — 系统级位置服务已禁用
authorizationDeniedGlobally: Bool - — 正在显示授权对话框
authorizationRequestInProgress: Bool - — 应用未获得足够的“使用中”状态权限
insufficientlyInUse: Bool - — 位置数据暂时不可用
locationUnavailable: Bool - — 授权精度已降低
accuracyLimited: Bool
SwiftUI Integration Pattern
SwiftUI 集成模式
swift
@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
}
}swift
@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
}
}Authorization Quick Reference
授权快速参考
Info.plist Keys (Required)
Info.plist 必要键值
| Key | When to Use |
|---|---|
| App uses location while in foreground |
| App needs location in background too |
| Request reduced accuracy by default |
| 键 | 使用场景 |
|---|---|
| 应用在前台使用位置信息 |
| 应用需要在后台也使用位置信息 |
| 默认请求降低精度的位置信息 |
Authorization Status Values (CLAuthorizationStatus
)
CLAuthorizationStatus授权状态值(CLAuthorizationStatus
)
CLAuthorizationStatus| Value | Meaning |
|---|---|
| User hasn't been asked yet |
| App cannot use location (e.g., parental controls) |
| User explicitly denied |
| App can use location while in foreground |
| App can use location at any time |
| 值 | 含义 |
|---|---|
| 尚未询问用户授权 |
| 应用无法使用位置服务(如受家长控制限制) |
| 用户明确拒绝授权 |
| 应用可在前台使用位置信息 |
| 应用可随时使用位置信息 |
Requesting Authorization
请求授权
swift
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")swift
let manager = CLLocationManager()
// 仅前台访问权限
manager.requestWhenInUseAuthorization()
// 后台访问权限(需先获得“使用期间”权限)
manager.requestAlwaysAuthorization()
// 请求临时高精度授权(当用户已授予降低精度权限时)
manager.requestTemporaryFullAccuracyAuthorization(withPurposeKey: "MyPurposeKey")Condition Monitoring with CLMonitor (iOS 17+)
基于CLMonitor的条件监控(iOS 17+)
swift
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
}
}swift
let monitor = await CLMonitor("myMonitor")
// 添加圆形地理区域条件
await monitor.add(
CLMonitor.CircularGeographicCondition(center: coordinate, radius: 200),
identifier: "coffee-shop"
)
// 监听事件
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
}
}Geocoding Quick Reference
地理编码快速参考
swift
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)
}
}swift
let geocoder = CLGeocoder()
// 逆地理编码:坐标 → 地址
geocoder.reverseGeocodeLocation(location) { placemarks, error in
if let placemark = placemarks?.first {
print(placemark.locality ?? "Unknown city")
}
}
// 正向地理编码:地址 → 坐标
geocoder.geocodeAddressString("1 Apple Park Way, Cupertino") { placemarks, error in
if let location = placemarks?.first?.location {
print(location.coordinate)
}
}CLLocation Key Properties
CLLocation 核心属性
| Property | Type | Description |
|---|---|---|
| | Latitude and longitude (WGS 84) |
| | Meters above sea level |
| | Accuracy in meters (negative = invalid) |
| | Altitude accuracy in meters |
| | Meters per second |
| | Degrees relative to true north |
| | When the location was determined |
| | Floor of a building, if available |
| | Info about the location source |
| 属性 | 类型 | 描述 |
|---|---|---|
| | 纬度和经度(WGS 84标准) |
| | 海拔高度(米,相对于海平面) |
| | 水平精度(米,负值表示无效) |
| | 垂直精度(米) |
| | 移动速度(米/秒) |
| | 航向(相对于真北的角度,度) |
| | 位置信息的获取时间 |
| | 所在楼层(如果可用) |
| | 位置信息来源的相关信息 |
Power Optimization Guidelines
功耗优化指南
Choose the most power-efficient service for your use case:
-
Visits service () — Most power-efficient. Reports places visited and time spent. Good for: check-in apps, travel logs.
startMonitoringVisits() -
Significant-change service () — Low power, uses Wi-Fi/cellular only. Good for: approximate location tracking.
startMonitoringSignificantLocationChanges() -
Standard location service () — Configurable accuracy via
startUpdatingLocation(). Good for: navigation, fitness tracking.desiredAccuracy -
Live updates () — Modern async API with configurable activity types. Good for: any new project on iOS 17+.
CLLocationUpdate.liveUpdates()
根据你的使用场景选择最节能的服务:
- 到访服务()—— 最节能,报告用户到访的地点和停留时间。适用于:签到应用、旅行日志。
startMonitoringVisits() - 重要位置变更服务()—— 低功耗,仅使用Wi-Fi/蜂窝网络。适用于:大致位置追踪。
startMonitoringSignificantLocationChanges() - 标准位置服务()—— 精度可通过
startUpdatingLocation()配置。适用于:导航、健身追踪。desiredAccuracy - 实时更新()—— 现代化异步API,支持配置活动类型。适用于:iOS 17+的所有新项目。
CLLocationUpdate.liveUpdates()
Desired Accuracy Constants
目标精度常量
| Constant | Description |
|---|---|
| Highest precision, most power |
| Best available accuracy |
| Within ~10 meters |
| Within ~100 meters |
| Within ~1 km |
| Within ~3 km |
| Deliberately reduced accuracy |
| 常量 | 描述 |
|---|---|
| 最高精度,功耗最大 |
| 可用的最佳精度 |
| 精度约10米以内 |
| 精度约100米以内 |
| 精度约1公里以内 |
| 精度约3公里以内 |
| 刻意降低的精度 |
Platform Considerations
平台注意事项
- visionOS: Location services are limited. Background updates are not supported. Region monitoring methods do nothing for compatible iPad/iPhone apps running in visionOS.
- macOS: Apps are not suspended in background, so no special background capability needed.
- watchOS: Supports background location with capability. Use .
CLBackgroundActivitySession - Widgets: Check for widget eligibility.
isAuthorizedForWidgetUpdates
- visionOS:位置服务受限,不支持后台更新。兼容的iPad/iPhone应用在visionOS中运行时,区域监控方法无效。
- macOS:应用在后台不会被挂起,因此无需特殊的后台权限。
- watchOS:支持带权限的后台位置服务,需使用。
CLBackgroundActivitySession - 小组件:需检查以确认小组件是否具备使用权限。
isAuthorizedForWidgetUpdates
Common Pitfalls
常见误区
- Always check — negative values mean the coordinate is invalid.
horizontalAccuracy - Do not assume location is immediately available after starting services.
- Handle authorization changes gracefully; users can revoke at any time via Settings.
- Geocoder requests are rate-limited; cache results and do not geocode on every location update.
- The system can pause location updates automatically. Set and
pausesLocationUpdatesAutomaticallyto help CoreLocation make good decisions.activityType - For background updates on iOS: add the "Location updates" background mode capability
AND set on the location manager.
allowsBackgroundLocationUpdates = true
- 始终检查——负值表示坐标无效。
horizontalAccuracy - 不要假设启动服务后位置信息会立即可用。
- 优雅处理授权变更;用户可随时通过设置撤销授权。
- 地理编码请求有频率限制;请缓存结果,不要在每次位置更新时都进行地理编码。
- 系统可能会自动暂停位置更新。设置和
pausesLocationUpdatesAutomatically可帮助CoreLocation做出合理决策。activityType - 对于iOS后台更新:需添加“位置更新”后台模式权限,并且在位置管理器上设置。
allowsBackgroundLocationUpdates = true