2024 Privacy & SecurityMaps & Location
WWDC24 · 18 min · Privacy & Security / Maps & Location
What’s new in location authorization
Location authorization is turning 2.0. Learn about new recommendations and techniques to get the authorization you need, and a new system of diagnostics that can let you know when an authorization goal can’t be met.
Watch at developer.apple.com ↗Chapters
Code shown on screen · 9 snippets
CLLocationUpdate and CLMonitor
// Iterating liveUpdates to reflect current location
Task {
let updates = CLLocationUpdate.liveUpdates()
for try await update in updates {
if let loc = update.location {
updateLocationUI(location: loc)
}
}
}
// Iterating monitor events to report condition state changes
Task {
let monitor = await CLMonitor(monitorName)
await monitor.add(CLMonitor.CircularGeographicCondition(center: applePark, radius: 50),
identifier: "ApplePark")
for try await event in await monitor.events {
updateConditionsUI(for: event.identifier, state: event.state)
}
} Handle updates with CLLocationManagerDelegate
// Adapting location authorization to Swift with a MainActor singleton
class LocationReflector: NSObject, CLLocationManagerDelegate, ObservableObject {
static let shared = LocationReflector()
private let manager = CLLocationManager()
override init() {
super.init()
manager.delegate = self
}
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager){
if (manager.authorizationStatus == .notDetermined) {
manager.requestWhenInUseAuthorization()
}
}
func locationManager(_ manager: CLLocationManager,
didUpdateLocations locations:[CLLocation]) {
// Process locations[0]
}
// ...
} CLServiceSession simplifies
// CLServiceSession in action
Task {
let session = CLServiceSession(authorization: .whenInUse)
for try await update in CLLocationUpdate.liveUpdates {
// Process update.location or update.authorizationDenied
}
} Implicit service sessions
// CLServiceSession in action
Task {
let session = CLServiceSession(authorization: .whenInUse)
for try await update in CLLocationUpdate.liveUpdates {
// Process update.location or update.authorizationDenied
}
} Implicit service sessions
Task {
for try await update in CLLocationUpdate.liveUpdates {
// Process update.location or update.authorizationDenied
}
} Diagnostics – Following the progress of location authorization
// Following the progress of location authorization with CLServiceSession
let mySession = CLServiceSession(authorization:.whenInUse)
for try await diagnostic in mySession.diagnostics {
if (diagnostic.authorizationDenied) {
// Ok, let’s let them pick a location instead?
}
} Diagnostics – Following the progress of location authorization
// Following the progress of location authorization with CLServiceSession
let mySession = CLServiceSession(authorization:.whenInUse)
for try await diagnostic in mySession.diagnostics {
if (!diagnostic.authorizationRequestInProgress) {
// They’ve decided (maybe already). We can move on!
break
}
} Diagnostics – Following the progress of location authorization
// Following the progress of location authorization with CLServiceSession
let mySession = CLServiceSession(authorization:.whenInUse)
for try await diagnostic in mySession.diagnostics {
if (!diagnostic.authorizationRequestInProgress) {
reactToChanges(authorized:!diagnostic.authorizationDenied)
}
} Diagnostics – Following the progress of location authorization
// Following the progress of location authorization with CLServiceSession
Task {
let mySession = CLServiceSession(authorization:.whenInUse)
for try await diagnostic in mySession.diagnostics {
if (!diagnostic.authorizationRequestInProgress) {
reactToChanges(authorized:!diagnostic.authorizationDenied)
}
}
}