axiom-core-location
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCore Location Patterns
Core Location 实现模式
Discipline skill for Core Location implementation decisions. Prevents common authorization mistakes, battery drain, and background location failures.
这是Core Location实现决策的规范技能,可避免常见的授权错误、电池消耗过快以及后台定位失败问题。
When to Use
适用场景
- Choosing authorization strategy (When In Use vs Always)
- Deciding monitoring approach (continuous vs significant-change vs CLMonitor)
- Implementing geofencing or background location
- Debugging "location not working" issues
- Reviewing location code for anti-patterns
- 选择授权策略(使用时授权 vs 始终授权)
- 确定监控方式(持续监控 vs 显著变化监控 vs CLMonitor)
- 实现地理围栏或后台定位
- 排查「定位无法工作」问题
- 审查定位代码中的反模式
Related Skills
相关技能
- — API reference, code examples
axiom-core-location-ref - — Symptom-based troubleshooting
axiom-core-location-diag - — Location as battery subsystem
axiom-energy
- — API参考、代码示例
axiom-core-location-ref - — 基于症状的故障排查
axiom-core-location-diag - — 定位作为电池子系统
axiom-energy
Part 1: Anti-Patterns (with Time Costs)
第一部分:反模式(附修复时间成本)
Anti-Pattern 1: Premature Always Authorization
反模式1:过早请求始终授权
Wrong (30-60% denial rate):
swift
// First launch: "Can we have Always access?"
manager.requestAlwaysAuthorization()Right (5-10% denial rate):
swift
// Start with When In Use
CLServiceSession(authorization: .whenInUse)
// Later, when user triggers background feature:
CLServiceSession(authorization: .always)Time cost: 15 min to fix code, but 30-60% of users permanently denied = feature adoption destroyed.
Why: Users deny aggressive requests. Start minimal, upgrade when user understands value.
错误做法(30-60%的拒绝率):
swift
// 首次启动:"能否获取始终授权?"
manager.requestAlwaysAuthorization()正确做法(5-10%的拒绝率):
swift
// 先使用「使用时授权」
CLServiceSession(authorization: .whenInUse)
// 后续当用户触发后台功能时:
CLServiceSession(authorization: .always)时间成本:修复代码需15分钟,但30-60%的用户会永久拒绝授权,直接导致功能使用率大幅下降。
原因:用户会拒绝过于激进的请求。应从最小权限开始,当用户理解功能价值后再升级权限。
Anti-Pattern 2: Continuous Updates for Geofencing
反模式2:为地理围栏使用持续更新
Wrong (10x battery drain):
swift
for try await update in CLLocationUpdate.liveUpdates() {
if isNearTarget(update.location) {
triggerGeofence()
}
}Right (system-managed, low power):
swift
let monitor = await CLMonitor("Geofences")
let condition = CLMonitor.CircularGeographicCondition(
center: target, radius: 100
)
await monitor.add(condition, identifier: "Target")
for try await event in monitor.events {
if event.state == .satisfied { triggerGeofence() }
}Time cost: 5 min to refactor, saves 10x battery.
错误做法(电池消耗增加10倍):
swift
for try await update in CLLocationUpdate.liveUpdates() {
if isNearTarget(update.location) {
triggerGeofence()
}
}正确做法(系统管理,低功耗):
swift
let monitor = await CLMonitor("Geofences")
let condition = CLMonitor.CircularGeographicCondition(
center: target, radius: 100
)
await monitor.add(condition, identifier: "Target")
for try await event in monitor.events {
if event.state == .satisfied { triggerGeofence() }
}时间成本:重构代码需5分钟,可减少10倍电池消耗。
Anti-Pattern 3: Ignoring Stationary Detection
反模式3:忽略静止状态检测
Wrong (wasted battery):
swift
for try await update in CLLocationUpdate.liveUpdates() {
processLocation(update.location)
// Never stops, even when device stationary
}Right (automatic pause/resume):
swift
for try await update in CLLocationUpdate.liveUpdates() {
if let location = update.location {
processLocation(location)
}
if update.isStationary, let location = update.location {
// Device stopped moving - updates pause automatically
// Will resume when device moves again
saveLastKnownLocation(location)
}
}Time cost: 2 min to add check, saves significant battery.
错误做法(浪费电池):
swift
for try await update in CLLocationUpdate.liveUpdates() {
processLocation(update.location)
// 设备静止时仍持续更新
}正确做法(自动暂停/恢复):
swift
for try await update in CLLocationUpdate.liveUpdates() {
if let location = update.location {
processLocation(location)
}
if update.isStationary, let location = update.location {
// 设备停止移动时,更新会自动暂停
// 设备再次移动时恢复更新
saveLastKnownLocation(location)
}
}时间成本:添加检测逻辑需2分钟,可显著节省电量。
Anti-Pattern 4: No Graceful Denial Handling
反模式4:未处理授权拒绝的优雅降级
Wrong (broken UX):
swift
for try await update in CLLocationUpdate.liveUpdates() {
guard let location = update.location else { continue }
// User denied - silent failure, no feedback
}Right (graceful degradation):
swift
for try await update in CLLocationUpdate.liveUpdates() {
if update.authorizationDenied {
showManualLocationPicker()
break
}
if update.authorizationDeniedGlobally {
showSystemLocationDisabledMessage()
break
}
if let location = update.location {
processLocation(location)
}
}Time cost: 10 min to add handling, prevents confused users.
错误做法(体验破碎):
swift
for try await update in CLLocationUpdate.liveUpdates() {
guard let location = update.location else { continue }
// 用户拒绝授权后无提示,静默失败
}正确做法(优雅降级):
swift
for try await update in CLLocationUpdate.liveUpdates() {
if update.authorizationDenied {
showManualLocationPicker()
break
}
if update.authorizationDeniedGlobally {
showSystemLocationDisabledMessage()
break
}
if let location = update.location {
processLocation(location)
}
}时间成本:添加处理逻辑需10分钟,避免用户困惑。
Anti-Pattern 5: Wrong Accuracy for Use Case
反模式5:精度与使用场景不匹配
Wrong (battery drain for weather app):
swift
// Weather app using navigation accuracy
CLLocationUpdate.liveUpdates(.automotiveNavigation)Right (match accuracy to need):
swift
// Weather: city-level is fine
CLLocationUpdate.liveUpdates(.default) // or .fitness for runners
// Navigation: needs high accuracy
CLLocationUpdate.liveUpdates(.automotiveNavigation)| Use Case | Configuration | Accuracy | Battery |
|---|---|---|---|
| Navigation | | ~5m | Highest |
| Fitness tracking | | ~10m | High |
| Store finder | | ~10-100m | Medium |
| Weather | | ~100m+ | Low |
Time cost: 1 min to change, significant battery savings.
错误做法(天气应用消耗过多电池):
swift
// 天气应用使用导航级精度
CLLocationUpdate.liveUpdates(.automotiveNavigation)正确做法(精度匹配需求):
swift
// 天气应用:城市级精度足够
CLLocationUpdate.liveUpdates(.default) // 跑步应用可使用.fitness
// 导航应用:需要高精度
CLLocationUpdate.liveUpdates(.automotiveNavigation)| 使用场景 | 配置项 | 精度 | 电池消耗 |
|---|---|---|---|
| 导航 | | ~5米 | 最高 |
| 健身追踪 | | ~10米 | 高 |
| 门店查找 | | ~10-100米 | 中等 |
| 天气 | | ~100米以上 | 低 |
时间成本:修改配置需1分钟,可显著节省电量。
Anti-Pattern 6: Not Stopping Updates
反模式6:未停止定位更新
Wrong (battery drain, location icon persists):
swift
func viewDidLoad() {
Task {
for try await update in CLLocationUpdate.liveUpdates() {
updateMap(update.location)
}
}
}
// User navigates away, updates continue foreverRight (cancel when done):
swift
private var locationTask: Task<Void, Error>?
func startTracking() {
locationTask = Task {
for try await update in CLLocationUpdate.liveUpdates() {
if Task.isCancelled { break }
updateMap(update.location)
}
}
}
func stopTracking() {
locationTask?.cancel()
locationTask = nil
}Time cost: 5 min to add cancellation, stops battery drain.
错误做法(电池消耗,定位图标持续显示):
swift
func viewDidLoad() {
Task {
for try await update in CLLocationUpdate.liveUpdates() {
updateMap(update.location)
}
}
}
// 用户离开页面后,更新仍持续进行正确做法(使用完成后取消):
swift
private var locationTask: Task<Void, Error>?
func startTracking() {
locationTask = Task {
for try await update in CLLocationUpdate.liveUpdates() {
if Task.isCancelled { break }
updateMap(update.location)
}
}
}
func stopTracking() {
locationTask?.cancel()
locationTask = nil
}时间成本:添加取消逻辑需5分钟,停止不必要的电池消耗。
Anti-Pattern 7: Ignoring CLServiceSession (iOS 18+)
反模式7:忽略CLServiceSession(iOS 18+)
Wrong (procedural authorization juggling):
swift
func requestAuth() {
switch manager.authorizationStatus {
case .notDetermined:
manager.requestWhenInUseAuthorization()
case .authorizedWhenInUse:
if needsFullAccuracy {
manager.requestTemporaryFullAccuracyAuthorization(...)
}
// Complex state machine...
}
}Right (declarative goals):
swift
// Just declare what you need - Core Location handles the rest
let session = CLServiceSession(authorization: .whenInUse)
// For feature needing full accuracy
let navSession = CLServiceSession(
authorization: .whenInUse,
fullAccuracyPurposeKey: "Navigation"
)
// Monitor diagnostics if needed
for try await diag in session.diagnostics {
if diag.authorizationDenied { handleDenial() }
}Time cost: 30 min to migrate, simpler code, fewer bugs.
错误做法(繁琐的授权状态管理):
swift
func requestAuth() {
switch manager.authorizationStatus {
case .notDetermined:
manager.requestWhenInUseAuthorization()
case .authorizedWhenInUse:
if needsFullAccuracy {
manager.requestTemporaryFullAccuracyAuthorization(...)
}
// 复杂的状态机逻辑...
}
}正确做法(声明式目标):
swift
// 只需声明需求,Core Location会处理后续逻辑
let session = CLServiceSession(authorization: .whenInUse)
// 对于需要全精度的功能
let navSession = CLServiceSession(
authorization: .whenInUse,
fullAccuracyPurposeKey: "Navigation"
)
// 如需监控诊断信息
for try await diag in session.diagnostics {
if diag.authorizationDenied { handleDenial() }
}时间成本:迁移代码需30分钟,代码更简洁,bug更少。
Part 2: Decision Trees
第二部分:决策树
Authorization Strategy
授权策略
Q1: Does your feature REQUIRE background location?
├─ NO → Use .whenInUse
│ └─ Q2: Does any feature need precise location?
│ ├─ ALWAYS → Add fullAccuracyPurposeKey to session
│ └─ SOMETIMES → Layer full-accuracy session when feature active
│
└─ YES → Start with .whenInUse, upgrade to .always when user triggers feature
└─ Q3: When does user first need background location?
├─ IMMEDIATELY (e.g., fitness tracker) → Request .always on first relevant action
└─ LATER (e.g., geofence reminders) → Add .always session when user creates first geofence问题1:你的功能是否**必须**使用后台定位?
├─ 否 → 使用.whenInUse
│ └─ 问题2:是否有功能需要精确定位?
│ ├─ 始终需要 → 在session中添加fullAccuracyPurposeKey
│ └─ 有时需要 → 功能激活时再创建全精度session
│
└─ 是 → 先使用.whenInUse,当用户触发功能时再升级为.always
└─ 问题3:用户首次需要后台定位的时机?
├─ 立即需要(如健身追踪器)→ 用户首次执行相关操作时请求.always
└─ 后续需要(如地理围栏提醒)→ 用户创建第一个地理围栏时添加.always sessionMonitoring Strategy
监控策略
Q1: What are you monitoring for?
├─ USER POSITION (continuous tracking)
│ └─ Use CLLocationUpdate.liveUpdates()
│ └─ Q2: What activity?
│ ├─ Driving navigation → .automotiveNavigation
│ ├─ Walking/cycling nav → .otherNavigation
│ ├─ Fitness tracking → .fitness
│ ├─ Airplane apps → .airborne
│ └─ General → .default or omit
│
├─ ENTRY/EXIT REGIONS (geofencing)
│ └─ Use CLMonitor with CircularGeographicCondition
│ └─ Note: Maximum 20 conditions per app
│
├─ BEACON PROXIMITY
│ └─ Use CLMonitor with BeaconIdentityCondition
│ └─ Choose granularity: UUID only, UUID+major, UUID+major+minor
│
└─ SIGNIFICANT CHANGES ONLY (lowest power)
└─ Use startMonitoringSignificantLocationChanges() (legacy)
└─ Updates ~500m movements, works in background问题1:你要监控什么?
├─ 用户位置(持续追踪)
│ └─ 使用CLLocationUpdate.liveUpdates()
│ └─ 问题2:用户的活动类型?
│ ├─ 驾车导航 → .automotiveNavigation
│ ├─ 步行/骑行导航 → .otherNavigation
│ ├─ 健身追踪 → .fitness
│ ├─ 飞行应用 → .airborne
│ └─ 通用场景 → .default或省略
│
├─ 区域进入/退出(地理围栏)
│ └─ 使用CLMonitor搭配CircularGeographicCondition
│ └─ 注意:每个应用最多支持20个条件
│
├─ Beacon proximity(信标接近)
│ └─ 使用CLMonitor搭配BeaconIdentityCondition
│ └─ 选择粒度:仅UUID、UUID+major、UUID+major+minor
│
└─ 仅显著变化(最低功耗)
└─ 使用startMonitoringSignificantLocationChanges()(旧版API)
└─ 移动约500米时更新,支持后台运行Accuracy Selection
精度选择
Q1: What's the minimum accuracy that makes your feature work?
├─ TURN-BY-TURN NAV needs 5-10m → .automotiveNavigation / .otherNavigation
├─ FITNESS TRACKING needs 10-20m → .fitness
├─ STORE FINDER needs 100m → .default
├─ WEATHER/CITY needs 1km+ → .default (reduced accuracy acceptable)
└─ GEOFENCING uses system determination → CLMonitor handles it
Q2: Will user be moving fast?
├─ DRIVING (high speed) → .automotiveNavigation (extra processing for speed)
├─ CYCLING/WALKING → .otherNavigation
└─ STATIONARY/SLOW → .default
Always start with lowest acceptable accuracy. Higher accuracy = higher battery drain.问题1:你的功能正常工作所需的最低精度是多少?
├─ 逐向导航需要5-10米 → .automotiveNavigation / .otherNavigation
├─ 健身追踪需要10-20米 → .fitness
├─ 门店查找需要100米 → .default
├─ 天气/城市级应用需要1公里以上 → .default(可接受降低精度)
└─ 地理围栏由系统决定精度 → CLMonitor自动处理
问题2:用户是否会快速移动?
├─ 驾车(高速)→ .automotiveNavigation(针对速度优化额外处理)
├─ 骑行/步行 → .otherNavigation
└─ 静止/慢速 → .default
始终从可接受的最低精度开始。精度越高,电池消耗越大。Part 3: Pressure Scenarios
第三部分:压力场景
Scenario 1: "Just Use Always Authorization"
场景1:「直接使用始终授权即可」
Context: PM says "Users want location reminders. Just request Always access on first launch so it works."
Pressure: Ship fast, seems simpler.
Reality:
- 30-60% of users will deny Always authorization when asked upfront
- Users who deny can only re-enable in Settings (most won't)
- Feature adoption destroyed before users understand value
Response:
"Always authorization has 30-60% denial rates when requested upfront. We should start with When In Use, then request Always upgrade when the user creates their first location reminder. This gives us a 5-10% denial rate because users understand why they need it."
Evidence: Apple's own guidance in WWDC 2024-10212: "CLServiceSessions should be taken proactively... hold one requiring full-accuracy when people engage a feature that would warrant a special ask for it."
背景:产品经理说「用户需要位置提醒功能,首次启动就请求始终授权,这样就能正常工作了。」
压力:要求快速上线,看似更简单。
实际情况:
- 首次请求始终授权的拒绝率高达30-60%
- 拒绝授权的用户只能在设置中重新开启(大多数不会这么做)
- 用户还没理解功能价值就拒绝,直接摧毁功能使用率
应对话术:
「首次请求始终授权的拒绝率高达30-60%。我们应该先使用使用时授权,当用户创建第一个位置提醒时,再请求升级为始终授权。这样拒绝率只有5-10%,因为用户此时已经理解了功能的价值。」
依据:苹果在WWDC 2024-10212中的官方指导:「应主动使用CLServiceSession……当用户使用需要特殊权限的功能时,再创建全精度的session。」
Scenario 2: "Location Isn't Working in Background"
场景2:「后台定位无法工作」
Context: QA reports "App stops getting location when backgrounded."
Pressure: Quick fix before release.
Wrong fixes:
- Add all background modes
- Use without understanding
allowsBackgroundLocationUpdates = true - Request Always authorization
Right diagnosis:
- Check background mode capability exists
- Check CLBackgroundActivitySession is held (not deallocated)
- Check session started from foreground
- Check authorization level (.whenInUse works with CLBackgroundActivitySession)
Response:
"Background location requires specific setup. Let me check: (1) Background mode capability, (2) CLBackgroundActivitySession held during tracking, (3) session started from foreground. Missing any of these causes silent failure."
Checklist:
swift
// 1. Signing & Capabilities → Background Modes → Location updates
// 2. Hold session reference (property, not local variable)
var backgroundSession: CLBackgroundActivitySession?
func startBackgroundTracking() {
// 3. Must start from foreground
backgroundSession = CLBackgroundActivitySession()
startLocationUpdates()
}背景:QA反馈「应用进入后台后就无法获取位置了。」
压力:要求在发布前快速修复。
错误修复方式:
- 添加所有后台模式
- 不理解原理就设置
allowsBackgroundLocationUpdates = true - 请求始终授权
正确诊断步骤:
- 检查是否已添加后台模式权限
- 检查CLBackgroundActivitySession是否被持有(未被释放)
- 检查session是否从前台启动
- 检查授权级别(.whenInUse搭配CLBackgroundActivitySession可正常工作)
应对话术:
「后台定位需要特定的配置。让我检查:(1) 是否添加了后台模式权限;(2) 追踪期间是否持有CLBackgroundActivitySession;(3) session是否从前台启动。缺少任何一项都会导致静默失败。」
检查清单代码:
swift
// 1. 签名与功能 → 后台模式 → 位置更新
// 2. 持有session引用(属性,而非局部变量)
var backgroundSession: CLBackgroundActivitySession?
func startBackgroundTracking() {
// 3. 必须从前台启动
backgroundSession = CLBackgroundActivitySession()
startLocationUpdates()
}Scenario 3: "Geofence Events Aren't Firing"
场景3:「地理围栏事件未触发」
Context: Geofences work in testing but not in production for some users.
Pressure: "It works on my device" dismissal.
Common causes:
- Too many conditions: Maximum 20 per app
- Radius too small: Minimum ~100m for reliable triggering
- Overlapping regions: Can cause confusion
- Not awaiting events: Events only become lastEvent after handled
- Not reinitializing on launch: Monitor must be recreated
Response:
"Geofencing has several system constraints. Check: (1) Are we within the 20-condition limit? (2) Are all radii at least 100m? (3) Is the app reinitializing CLMonitor on launch? (4) Is the app always awaiting on monitor.events?"
Diagnostic code:
swift
// Check condition count
let count = await monitor.identifiers.count
if count >= 20 {
print("At 20-condition limit!")
}
// Check all conditions
for id in await monitor.identifiers {
if let record = await monitor.record(for: id) {
let condition = record.condition
if let geo = condition as? CLMonitor.CircularGeographicCondition {
if geo.radius < 100 {
print("Radius too small: \(id)")
}
}
}
}背景:地理围栏在测试环境正常,但部分生产环境用户无法触发。
压力:被以「我这里正常」为由忽略问题。
常见原因:
- 条件过多:每个应用最多支持20个条件
- 半径过小:可靠触发的最小半径约为100米
- 区域重叠:可能导致逻辑混乱
- 未等待事件:事件只有在处理后才会成为lastEvent
- 启动时未重新初始化:必须重新创建Monitor
应对话术:
「地理围栏有多个系统限制。请检查:(1) 是否超过20个条件的上限?(2) 所有半径是否至少为100米?(3) 应用启动时是否重新初始化CLMonitor?(4) 应用是否始终在等待monitor.events?」
诊断代码:
swift
// 检查条件数量
let count = await monitor.identifiers.count
if count >= 20 {
print("已达到20个条件的上限!")
}
// 检查所有条件
for id in await monitor.identifiers {
if let record = await monitor.record(for: id) {
let condition = record.condition
if let geo = condition as? CLMonitor.CircularGeographicCondition {
if geo.radius < 100 {
print("半径过小:\(id)")
}
}
}
}Part 4: Checklists
第四部分:检查清单
Pre-Release Location Checklist
发布前定位检查清单
Info.plist:
- with clear explanation
NSLocationWhenInUseUsageDescription - if using Always (clear why background needed)
NSLocationAlwaysAndWhenInUseUsageDescription - if reduced accuracy acceptable
NSLocationDefaultAccuracyReduced - if requesting temporary full accuracy
NSLocationTemporaryUsageDescriptionDictionary - includes
UIBackgroundModesif background trackinglocation
Authorization:
- Start with minimal authorization (.whenInUse)
- Upgrade to .always only when user triggers background feature
- Handle authorization denial gracefully (offer alternatives)
- Handle global location services disabled
- Test with reduced accuracy authorization
Updates:
- Using appropriate LiveConfiguration for use case
- Handling isStationary for pause/resume
- Cancelling location tasks when feature inactive
- Not using continuous updates for geofencing
Testing:
- Tested authorization denial flow
- Tested reduced accuracy mode
- Tested background-to-foreground transitions
- Tested app termination and relaunch recovery
Info.plist:
- 包含清晰的说明
NSLocationWhenInUseUsageDescription - 若使用始终授权,需明确说明后台定位的必要性
NSLocationAlwaysAndWhenInUseUsageDescription - 若可接受降低精度,添加
NSLocationDefaultAccuracyReduced - 若请求临时全精度,添加
NSLocationTemporaryUsageDescriptionDictionary - 若使用后台追踪,包含
UIBackgroundModeslocation
授权:
- 从最小权限开始(.whenInUse)
- 仅当用户触发后台功能时才升级为.always
- 优雅处理授权拒绝(提供替代方案)
- 处理全局定位服务禁用的情况
- 测试降低精度授权的场景
更新:
- 根据使用场景选择合适的LiveConfiguration
- 处理isStationary状态以实现暂停/恢复
- 功能未激活时取消定位任务
- 不为地理围栏使用持续更新
测试:
- 测试授权拒绝流程
- 测试降低精度模式
- 测试后台到前台的切换
- 测试应用终止后重启的恢复逻辑
Background Location Checklist
后台定位检查清单
Setup:
- Background mode capability added (Location updates)
- CLBackgroundActivitySession created and HELD (not local variable)
- Session started from foreground
- Updates restarted on background launch in didFinishLaunchingWithOptions
Authorization:
- Using .whenInUse with CLBackgroundActivitySession, OR
- Using .always (but only if needed beyond background indicator)
Lifecycle:
- Persisting "was tracking" state for relaunch recovery
- Recreating CLBackgroundActivitySession on background launch
- Restarting CLLocationUpdate iteration on launch
- CLMonitor reinitialized with same name on launch
Testing:
- Blue background location indicator appears when backgrounded
- Updates continue when app backgrounded
- Updates resume after app suspended and resumed
- Updates resume after app terminated and relaunched
配置:
- 已添加后台模式权限(位置更新)
- 创建并持有CLBackgroundActivitySession(非局部变量)
- session从前台启动
- 在didFinishLaunchingWithOptions中重启后台启动时的更新
授权:
- 使用.whenInUse搭配CLBackgroundActivitySession,或
- 使用.always(仅当需要超出后台指示器的功能时)
生命周期:
- 持久化「正在追踪」状态以支持重启恢复
- 后台启动时重新创建CLBackgroundActivitySession
- 启动时重启CLLocationUpdate迭代
- 启动时使用相同名称重新初始化CLMonitor
测试:
- 进入后台后显示蓝色定位指示器
- 应用后台时更新持续进行
- 应用挂起后恢复时更新继续
- 应用终止后重启时更新恢复
Part 5: iOS Version Considerations
第五部分:iOS版本兼容性
| Feature | iOS Version | Notes |
|---|---|---|
| CLLocationUpdate | iOS 17+ | AsyncSequence API |
| CLMonitor | iOS 17+ | Replaces CLCircularRegion |
| CLBackgroundActivitySession | iOS 17+ | Background with blue indicator |
| CLServiceSession | iOS 18+ | Declarative authorization |
| Implicit service sessions | iOS 18+ | From iterating liveUpdates |
| CLLocationManager | iOS 2+ | Legacy but still works |
For iOS 14-16 support: Use CLLocationManager delegate pattern (see core-location-ref Part 7).
For iOS 17+: Prefer CLLocationUpdate and CLMonitor.
For iOS 18+: Add CLServiceSession for declarative authorization.
| 功能 | iOS版本 | 说明 |
|---|---|---|
| CLLocationUpdate | iOS 17+ | AsyncSequence API |
| CLMonitor | iOS 17+ | 替代CLCircularRegion |
| CLBackgroundActivitySession | iOS 17+ | 带蓝色指示器的后台定位 |
| CLServiceSession | iOS 18+ | 声明式授权 |
| 隐式service session | iOS 18+ | 从liveUpdates迭代自动创建 |
| CLLocationManager | iOS 2+ | 旧版API但仍可使用 |
iOS 14-16兼容方案:使用CLLocationManager代理模式(详见core-location-ref第7部分)。
iOS 17+:优先使用CLLocationUpdate和CLMonitor。
iOS 18+:添加CLServiceSession实现声明式授权。
Resources
资源
WWDC: 2023-10180, 2023-10147, 2024-10212
Docs: /corelocation, /corelocation/clmonitor, /corelocation/cllocationupdate, /corelocation/clservicesession
Skills: axiom-core-location-ref, axiom-core-location-diag, axiom-energy
WWDC:2023-10180, 2023-10147, 2024-10212
文档:/corelocation, /corelocation/clmonitor, /corelocation/cllocationupdate, /corelocation/clservicesession
相关技能:axiom-core-location-ref, axiom-core-location-diag, axiom-energy