Agent skill
ios-core-location
Use for Core Location implementation decisions: authorization strategy, monitoring mode, accuracy selection, geofencing, and background location lifecycle.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/other/ios-core-location
Metadata
Additional technical details for this skill
- version
- 1.0.0
- last updated
- 2026-01-03
SKILL.md
Core Location Patterns
Implementation discipline for location features: correct authorization, battery-aware tracking, and reliable background behavior.
Related Skills
- references/api-reference.md - API reference
Anti-Patterns (and cost)
1) Premature Always authorization
// Wrong
manager.requestAlwaysAuthorization()
// Right
CLServiceSession(authorization: .whenInUse)
// upgrade to .always only when user starts background feature
- Cost: fast code, poor adoption (high denial rates)
- Rule: start minimal, escalate with contextual user intent
2) Continuous updates for geofencing
// Wrong: polling location to emulate geofencing
for try await update in CLLocationUpdate.liveUpdates() { ... }
// Right: system geofencing
let monitor = await CLMonitor("Geofences")
await monitor.add(CLMonitor.CircularGeographicCondition(center: target, radius: 100), identifier: "Target")
for try await event in monitor.events { ... }
- Cost: major battery waste
- Rule: use
CLMonitorfor entry/exit semantics
3) Ignoring stationary behavior
for try await update in CLLocationUpdate.liveUpdates() {
if let location = update.location { processLocation(location) }
if update.isStationary { saveLastKnownLocation(update.location) }
}
- Cost: unnecessary processing while stationary
- Rule: respect stationary/pause behavior
4) No graceful denial path
for try await update in CLLocationUpdate.liveUpdates() {
if update.authorizationDenied { showManualLocationPicker(); break }
if update.authorizationDeniedGlobally { showSystemLocationDisabledMessage(); break }
if let location = update.location { processLocation(location) }
}
- Cost: silent failure + broken UX
- Rule: always branch explicit denial states
5) Wrong accuracy for use case
// Wrong for weather app
CLLocationUpdate.liveUpdates(.automotiveNavigation)
// Better by intent
CLLocationUpdate.liveUpdates(.default) // weather/store-finder
CLLocationUpdate.liveUpdates(.fitness) // activity
CLLocationUpdate.liveUpdates(.automotiveNavigation) // turn-by-turn
| Use case | Config | Typical accuracy | Battery |
|---|---|---|---|
| Navigation | .automotiveNavigation |
~5m | Highest |
| Fitness | .fitness |
~10m | High |
| Store finder | .default |
~10-100m | Medium |
| Weather | .default |
city-level | Low |
6) Not stopping updates
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
}
- Cost: battery drain + persistent location indicator
- Rule: explicit start/stop lifecycle
7) Ignoring CLServiceSession (iOS 18+)
let session = CLServiceSession(authorization: .whenInUse)
let navSession = CLServiceSession(
authorization: .whenInUse,
fullAccuracyPurposeKey: "Navigation"
)
for try await diag in session.diagnostics {
if diag.authorizationDenied { handleDenial() }
}
- Cost: manual state machine complexity
- Rule: declare needs; observe diagnostics
Decision Trees
Authorization
- Need background location?
- no ->
.whenInUse - yes -> start
.whenInUse, upgrade.alwaysat first background feature action
- Need precise location?
- always -> full accuracy purpose key
- sometimes -> temporary full-accuracy session only during relevant feature
Monitoring mode
- Track continuous position?
- use
CLLocationUpdate.liveUpdates()with matchingLiveConfiguration
- Entry/exit geofence?
- use
CLMonitor.CircularGeographicCondition(20-condition cap)
- Beacon proximity?
- use
CLMonitor.BeaconIdentityConditionwith needed granularity
- Low-power broad movement only?
- use significant-change monitoring (legacy API)
Accuracy selection
- pick lowest accuracy that still satisfies feature requirements
- high speed driving ->
.automotiveNavigation - walking/cycling ->
.otherNavigation - general/stationary ->
.default
Higher accuracy always increases energy cost.
Pressure Scenarios
"Request Always on first launch"
Response:
- upfront Always requests commonly increase denial
- use staged ask:
.whenInUsefirst, upgrade on feature trigger - reference CLServiceSession guidance for contextual asks
"Background location not working"
Checklist:
- background capability present
CLBackgroundActivitySessionretained- session started in foreground
- relaunch recovery restores session + update stream
"Geofence unreliable in production"
Checklist:
- <=20 conditions
- radius >=100m
- always await
monitor.events - recreate monitor on app launch
- inspect
lastEventandaccuracyLimited
Pre-Release Checklist
Info.plist
-
NSLocationWhenInUseUsageDescription -
NSLocationAlwaysAndWhenInUseUsageDescription(if applicable) -
NSLocationDefaultAccuracyReduced(if acceptable) -
NSLocationTemporaryUsageDescriptionDictionary(if requesting temporary full accuracy) -
UIBackgroundModesincludeslocation(if background tracking)
Authorization and UX
- Start with minimal auth
- Upgrade only at feature trigger
- Denial and global-disable paths handled
- Reduced-accuracy path tested
Runtime lifecycle
- Appropriate
LiveConfiguration - Stationary behavior handled
- Tasks canceled when inactive
- Geofencing not implemented via continuous polling
Testing
- Deny/re-enable flow tested
- Background/foreground transitions tested
- Termination + relaunch recovery tested
Background Location Checklist
Setup
- Capability enabled: Location updates
-
CLBackgroundActivitySessionretained strongly - Created in foreground
- Relaunch path rehydrates tracking state
Lifecycle
- Persist "tracking active" state
- Restore session and update stream on launch
- Reinitialize
CLMonitorwith same name
Version Guidance
| Feature | Minimum iOS | Note |
|---|---|---|
CLLocationUpdate |
17 | AsyncSequence API |
CLMonitor |
17 | Region/beacon monitoring |
CLBackgroundActivitySession |
17 | Background with indicator |
CLServiceSession |
18 | Declarative authorization |
- iOS 14-16: use
CLLocationManagerdelegate style. - iOS 17+: prefer
CLLocationUpdateandCLMonitor. - iOS 18+: add
CLServiceSession.
Resources
- WWDC: 2023-10180, 2023-10147, 2024-10212
- Docs:
/corelocation,/corelocation/clmonitor,/corelocation/cllocationupdate,/corelocation/clservicesession - Reference: references/api-reference.md
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?