Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

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 ↗

Transcript all transcripts

Chapters

Code shown on screen · 9 snippets

CLLocationUpdate and CLMonitor swift · at 0:31 ↗
// 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 swift · at 0:52 ↗
// Adapting location authorization to Swift with a MainActor singleton
@MainActor 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 swift · at 1:07 ↗
// 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 swift · at 7:15 ↗
// 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 swift · at 7:34 ↗
Task {
    for try await update in CLLocationUpdate.liveUpdates {
        // Process update.location or update.authorizationDenied
    }
}
Diagnostics – Following the progress of location authorization swift · at 13:37 ↗
// 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 swift · at 15:00 ↗
// 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 swift · at 15:25 ↗
// 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 swift · at 15:46 ↗
// 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)
        }
    }
}

Resources