Skip to content
intermediate Phase 8 · Media & Hardware

Core Location & Geofencing

Request location permissions, monitor regions, and implement background location updates.

45m
2 problems
Topic Progress 0%

Location Permissions

Info.plist Keys

Add usage descriptions:

  • NSLocationWhenInUseUsageDescription
  • NSLocationAlwaysAndWhenInUseUsageDescription

Requesting Permission

import CoreLocation

class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
    private let manager = CLLocationManager()
    @Published var location: CLLocation?
    
    override init() {
        super.init()
        manager.delegate = self
    }
    
    func requestPermission() {
        manager.requestWhenInUseAuthorization()
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        location = locations.last
    }
    
    func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
        if manager.authorizationStatus == .authorizedWhenInUse {
            manager.startUpdatingLocation()
        }
    }
}

Authorization Status

  • .notDetermined — Not yet requested
  • .restricted — Restricted by parental controls
  • .denied — User denied
  • .authorizedWhenInUse — Foreground access
  • .authorizedAlways — Background access

Getting Current Location

Start Location Updates

manager.requestLocation()  // One-time
manager.startUpdatingLocation()  // Continuous

Location Accuracy

manager.desiredAccuracy = kCLLocationAccuracyBest  // Highest accuracy
manager.desiredAccuracy = kCLLocationAccuracyHundredMeters  // Battery efficient
manager.distanceFilter = 100  // Update every 100 meters

Reverse Geocoding

let geocoder = CLGeocoder()
geocoder.reverseGeocodeLocation(location) { placemarks, error in
    if let placemark = placemarks?.first {
        print(placemark.name, placemark.locality, placemark.country)
    }
}

Location Value

if let location = location {
    print("Lat: \(location.coordinate.latitude)")
    print("Lon: \(location.coordinate.longitude)")
    print("Alt: \(location.altitude)")
    print("Speed: \(location.speed)")
}

Region Monitoring & Geofencing

Define a Region

let region = CLCircularRegion(
    center: CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194),
    radius: 100,
    identifier: "Office"
)
region.notifyOnEntry = true
region.notifyOnExit = true

Monitor Region

manager.startMonitoring(for: region)

func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
    print("Entered \(region.identifier)")
}

func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
    print("Exited \(region.identifier)")
}

Background Location

For always-on monitoring, use requestAlwaysAuthorization() and configure background modes in Info.plist.

Significant Location Changes

manager.startMonitoringSignificantLocationChanges()

Quiz

1. Which authorization allows background location updates?

Question 1 options

2. What is geofencing?

Question 2 options

Flashcards

Question

What is the difference between requestLocation and startUpdatingLocation?

Answer

requestLocation gives one location update. startUpdatingLocation gives continuous updates.

Question

What key is needed for location permission?

Answer

NSLocationWhenInUseUsageDescription in Info.plist.

Revision Notes

Key Takeaways

  • 1. Always request appropriate authorization level
  • 2. Use desiredAccuracy for battery optimization
  • 3. Geofencing requires Always authorization
  • 4. Handle authorization changes in delegate

Interview Tips

  • Explain when to use WhenInUse vs Always
  • Discuss battery impact of location services
  • Show geofencing implementation

Cheat Sheet

Core Location: request permission, start updating, handle delegate callbacks. Geofencing: define regions, start monitoring.