apple-corelocation

Apple CoreLocation Skill

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "apple-corelocation" with this command: npx skills add ios-agent/iosagent.dev/ios-agent-iosagent-dev-apple-corelocation

Apple CoreLocation Skill

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.

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 references/live-updates.md

SwiftUI apps, async location streams, background activity sessions

Authorization & Permissions references/authorization.md

Permission flows, Info.plist keys, authorization status handling

Region Monitoring & CLMonitor references/monitoring.md

Geofencing, condition monitoring, circular regions

Geocoding references/geocoding.md

Address ↔ coordinate conversion, reverse geocoding, CLPlacemark

iBeacon & Compass references/beacon-compass.md

Beacon ranging, heading updates, magnetometer

Background Location references/background.md

Background updates, CLBackgroundActivitySession, power optimization

CLLocationManager API references/location-manager.md

Full property/method reference for CLLocationManager

Modern CoreLocation (iOS 17+): Prefer Async/Await

Since iOS 17, CoreLocation supports Swift concurrency. Prefer the modern async API over the legacy delegate-based approach for new projects.

Getting Live Location Updates (Recommended Pattern)

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 .notDetermined . No explicit requestWhenInUseAuthorization() call is needed with this pattern, but you may still call it for controlled timing.

Live Updates with Accuracy Configuration

// 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 Properties

  • location: CLLocation? — The location, or nil if unavailable

  • isStationary: Bool — Whether the device is stationary

  • authorizationDenied: Bool — Authorization was denied

  • authorizationDeniedGlobally: Bool — Location services disabled system-wide

  • authorizationRequestInProgress: Bool — Auth dialog is being shown

  • insufficientlyInUse: Bool — App lacks sufficient "in use" state

  • locationUnavailable: Bool — Location data temporarily unavailable

  • accuracyLimited: Bool — Accuracy authorization is reduced

SwiftUI Integration Pattern

@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)

Key When to Use

NSLocationWhenInUseUsageDescription

App uses location while in foreground

NSLocationAlwaysAndWhenInUseUsageDescription

App needs location in background too

NSLocationDefaultAccuracyReduced

Request reduced accuracy by default

Authorization Status Values (CLAuthorizationStatus )

Value Meaning

.notDetermined

User hasn't been asked yet

.restricted

App cannot use location (e.g., parental controls)

.denied

User explicitly denied

.authorizedWhenInUse

App can use location while in foreground

.authorizedAlways

App can use location at any time

Requesting Authorization

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")

Condition Monitoring with 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 } }

Geocoding Quick Reference

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 Key Properties

Property Type Description

coordinate

CLLocationCoordinate2D

Latitude and longitude (WGS 84)

altitude

CLLocationDistance

Meters above sea level

horizontalAccuracy

CLLocationAccuracy

Accuracy in meters (negative = invalid)

verticalAccuracy

CLLocationAccuracy

Altitude accuracy in meters

speed

CLLocationSpeed

Meters per second

course

CLLocationDirection

Degrees relative to true north

timestamp

Date

When the location was determined

floor

CLFloor?

Floor of a building, if available

sourceInformation

CLLocationSourceInformation?

Info about the location source

Power Optimization Guidelines

Choose the most power-efficient service for your use case:

Visits service (startMonitoringVisits() ) — Most power-efficient. Reports places visited and time spent. Good for: check-in apps, travel logs.

Significant-change service (startMonitoringSignificantLocationChanges() ) — Low power, uses Wi-Fi/cellular only. Good for: approximate location tracking.

Standard location service (startUpdatingLocation() ) — Configurable accuracy via desiredAccuracy . Good for: navigation, fitness tracking.

Live updates (CLLocationUpdate.liveUpdates() ) — Modern async API with configurable activity types. Good for: any new project on iOS 17+.

Desired Accuracy Constants

Constant Description

kCLLocationAccuracyBestForNavigation

Highest precision, most power

kCLLocationAccuracyBest

Best available accuracy

kCLLocationAccuracyNearestTenMeters

Within ~10 meters

kCLLocationAccuracyHundredMeters

Within ~100 meters

kCLLocationAccuracyKilometer

Within ~1 km

kCLLocationAccuracyThreeKilometers

Within ~3 km

kCLLocationAccuracyReduced

Deliberately reduced accuracy

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 isAuthorizedForWidgetUpdates for widget eligibility.

Common Pitfalls

  • Always check horizontalAccuracy — negative values mean the coordinate is invalid.

  • 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 pausesLocationUpdatesAutomatically

and activityType to help CoreLocation make good decisions.

  • For background updates on iOS: add the "Location updates" background mode capability AND set allowsBackgroundLocationUpdates = true on the location manager.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

swiftui

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

widgetkit

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

metal-gpu

No summary provided by upstream source.

Repository SourceNeeds Review