axiom-core-location

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Core 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

相关技能

  • axiom-core-location-ref
    — API reference, code examples
  • axiom-core-location-diag
    — Symptom-based troubleshooting
  • axiom-energy
    — Location as battery subsystem

  • axiom-core-location-ref
    — API参考、代码示例
  • 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 CaseConfigurationAccuracyBattery
Navigation
.automotiveNavigation
~5mHighest
Fitness tracking
.fitness
~10mHigh
Store finder
.default
~10-100mMedium
Weather
.default
~100m+Low
Time cost: 1 min to change, significant battery savings.

错误做法(天气应用消耗过多电池):
swift
// 天气应用使用导航级精度
CLLocationUpdate.liveUpdates(.automotiveNavigation)
正确做法(精度匹配需求):
swift
// 天气应用:城市级精度足够
CLLocationUpdate.liveUpdates(.default)  // 跑步应用可使用.fitness

// 导航应用:需要高精度
CLLocationUpdate.liveUpdates(.automotiveNavigation)
使用场景配置项精度电池消耗
导航
.automotiveNavigation
~5米最高
健身追踪
.fitness
~10米
门店查找
.default
~10-100米中等
天气
.default
~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 forever
Right (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 session

Monitoring 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
    allowsBackgroundLocationUpdates = true
    without understanding
  • Request Always authorization
Right diagnosis:
  1. Check background mode capability exists
  2. Check CLBackgroundActivitySession is held (not deallocated)
  3. Check session started from foreground
  4. 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
  • 请求始终授权
正确诊断步骤
  1. 检查是否已添加后台模式权限
  2. 检查CLBackgroundActivitySession是否被持有(未被释放)
  3. 检查session是否从前台启动
  4. 检查授权级别(.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:
  1. Too many conditions: Maximum 20 per app
  2. Radius too small: Minimum ~100m for reliable triggering
  3. Overlapping regions: Can cause confusion
  4. Not awaiting events: Events only become lastEvent after handled
  5. 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)")
            }
        }
    }
}

背景:地理围栏在测试环境正常,但部分生产环境用户无法触发。
压力:被以「我这里正常」为由忽略问题。
常见原因
  1. 条件过多:每个应用最多支持20个条件
  2. 半径过小:可靠触发的最小半径约为100米
  3. 区域重叠:可能导致逻辑混乱
  4. 未等待事件:事件只有在处理后才会成为lastEvent
  5. 启动时未重新初始化:必须重新创建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:
  • NSLocationWhenInUseUsageDescription
    with clear explanation
  • NSLocationAlwaysAndWhenInUseUsageDescription
    if using Always (clear why background needed)
  • NSLocationDefaultAccuracyReduced
    if reduced accuracy acceptable
  • NSLocationTemporaryUsageDescriptionDictionary
    if requesting temporary full accuracy
  • UIBackgroundModes
    includes
    location
    if background tracking
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
  • 若使用后台追踪,
    UIBackgroundModes
    包含
    location
授权
  • 从最小权限开始(.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版本兼容性

FeatureiOS VersionNotes
CLLocationUpdateiOS 17+AsyncSequence API
CLMonitoriOS 17+Replaces CLCircularRegion
CLBackgroundActivitySessioniOS 17+Background with blue indicator
CLServiceSessioniOS 18+Declarative authorization
Implicit service sessionsiOS 18+From iterating liveUpdates
CLLocationManageriOS 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版本说明
CLLocationUpdateiOS 17+AsyncSequence API
CLMonitoriOS 17+替代CLCircularRegion
CLBackgroundActivitySessioniOS 17+带蓝色指示器的后台定位
CLServiceSessioniOS 18+声明式授权
隐式service sessioniOS 18+从liveUpdates迭代自动创建
CLLocationManageriOS 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