@@ -24,7 +24,7 @@ import Foundation
2424import CoreLocation
2525
2626public typealias AuthotizationContinuation = CheckedContinuation < CLAuthorizationStatus , Never >
27- public typealias AccuracyAuthorizationContinuation = CheckedContinuation < CLAccuracyAuthorization ? , Never >
27+ public typealias AccuracyAuthorizationContinuation = CheckedContinuation < CLAccuracyAuthorization ? , Error >
2828public typealias LocationOnceContinuation = CheckedContinuation < LocationUpdateEvent ? , Error >
2929public typealias LocationEnabledStream = AsyncStream < LocationEnabledEvent >
3030public typealias LocationStream = AsyncStream < LocationUpdateEvent >
@@ -59,8 +59,7 @@ public final class AsyncLocationManager {
5959 // Though undocumented, `locationServicesEnabled()` must not be called from the main thread. Otherwise,
6060 // we get a runtime warning "This method can cause UI unresponsiveness if invoked on the main thread"
6161 // Therefore, we use `Task.detached` to ensure we're off the main thread.
62- // Also, we force `try` as we expect no exceptions to be thrown from `locationServicesEnabled()`
63- try ! await Task . detached { CLLocationManager . locationServicesEnabled ( ) } . value
62+ await Task . detached { CLLocationManager . locationServicesEnabled ( ) } . value
6463 }
6564
6665 @available ( watchOS 6 . 0 , * )
@@ -133,7 +132,7 @@ public final class AsyncLocationManager {
133132 @available ( * , deprecated, message: " Use new function requestPermission(with:) " )
134133 @available ( watchOS 7 . 0 , * )
135134 public func requestAuthorizationWhenInUse( ) async -> CLAuthorizationStatus {
136- let authorizationPerformer = RequestAuthorizationPerformer ( )
135+ let authorizationPerformer = RequestAuthorizationPerformer ( currentStatus : getAuthorizationStatus ( ) )
137136 return await withTaskCancellationHandler ( operation: {
138137 await withCheckedContinuation { continuation in
139138 let authorizationStatus = getAuthorizationStatus ( )
@@ -155,7 +154,7 @@ public final class AsyncLocationManager {
155154 @available ( watchOS 7 . 0 , * )
156155 @available ( iOS 14 , * )
157156 public func requestAuthorizationAlways( ) async -> CLAuthorizationStatus {
158- let authorizationPerformer = RequestAuthorizationPerformer ( )
157+ let authorizationPerformer = RequestAuthorizationPerformer ( currentStatus : getAuthorizationStatus ( ) )
159158 return await withTaskCancellationHandler ( operation: {
160159 await withCheckedContinuation { continuation in
161160#if os(macOS)
@@ -197,8 +196,8 @@ public final class AsyncLocationManager {
197196 }
198197
199198 @available ( iOS 14 , watchOS 7 , * )
200- public func requestTemporaryFullAccuracyAuthorization( purposeKey: String ) async -> CLAccuracyAuthorization ? {
201- await locationPermissionTemporaryFullAccuracy ( purposeKey: purposeKey)
199+ public func requestTemporaryFullAccuracyAuthorization( purposeKey: String ) async throws -> CLAccuracyAuthorization ? {
200+ try await locationPermissionTemporaryFullAccuracy ( purposeKey: purposeKey)
202201 }
203202
204203 public func startUpdatingLocation( ) async -> LocationStream {
@@ -316,7 +315,7 @@ public final class AsyncLocationManager {
316315
317316extension AsyncLocationManager {
318317 private func locationPermissionWhenInUse( ) async -> CLAuthorizationStatus {
319- let authorizationPerformer = RequestAuthorizationPerformer ( )
318+ let authorizationPerformer = RequestAuthorizationPerformer ( currentStatus : getAuthorizationStatus ( ) )
320319 return await withTaskCancellationHandler ( operation: {
321320 await withCheckedContinuation { continuation in
322321 let authorizationStatus = getAuthorizationStatus ( )
@@ -334,7 +333,7 @@ extension AsyncLocationManager {
334333 }
335334
336335 private func locationPermissionAlways( ) async -> CLAuthorizationStatus {
337- let authorizationPerformer = RequestAuthorizationPerformer ( )
336+ let authorizationPerformer = RequestAuthorizationPerformer ( currentStatus : getAuthorizationStatus ( ) )
338337 return await withTaskCancellationHandler ( operation: {
339338 await withCheckedContinuation { continuation in
340339#if os(macOS)
@@ -361,24 +360,61 @@ extension AsyncLocationManager {
361360 }
362361
363362 @available ( iOS 14 , watchOS 7 , * )
364- private func locationPermissionTemporaryFullAccuracy( purposeKey: String ) async -> CLAccuracyAuthorization ? {
363+ private func locationPermissionTemporaryFullAccuracy( purposeKey: String ) async throws -> CLAccuracyAuthorization ? {
365364 let authorizationPerformer = RequestAccuracyAuthorizationPerformer ( )
366- return await withTaskCancellationHandler ( operation: {
367- await withCheckedContinuation { continuation in
368- if locationManager. authorizationStatus != . notDetermined && locationManager. accuracyAuthorization == . fullAccuracy {
369- continuation. resume ( with: . success( locationManager. accuracyAuthorization) )
370- } else if locationManager. authorizationStatus == . notDetermined {
365+ return try await withTaskCancellationHandler ( operation: {
366+ try await withCheckedThrowingContinuation { ( continuation: CheckedContinuation < CLAccuracyAuthorization ? , Error > ) in
367+ if locationManager. authorizationStatus == . notDetermined {
371368 continuation. resume ( with: . success( nil ) )
369+ } else if locationManager. accuracyAuthorization == . fullAccuracy {
370+ continuation. resume ( with: . success( locationManager. accuracyAuthorization) )
372371 } else if !CLLocationManager. locationServicesEnabled ( ) {
373372 continuation. resume ( with: . success( nil ) )
374373 } else {
375374 authorizationPerformer. linkContinuation ( continuation)
376375 proxyDelegate. addPerformer ( authorizationPerformer)
377- locationManager. requestTemporaryFullAccuracyAuthorization ( withPurposeKey: purposeKey)
376+ locationManager. requestTemporaryFullAccuracyAuthorization ( withPurposeKey: purposeKey) { error in
377+ if let error {
378+ continuation. resume ( with: . failure( error) )
379+ return
380+ }
381+
382+ // If the user chooses reduced accuracy, the didChangeAuthorization delegate method
383+ // will not called. So we must emulate that here.
384+ if self . locationManager. accuracyAuthorization == . reducedAccuracy {
385+ self . proxyDelegate. eventForMethodInvoked (
386+ . didChangeAccuracyAuthorization( authorization: self . locationManager. accuracyAuthorization)
387+ )
388+ }
389+ }
378390 }
379391 }
380392 } , onCancel: {
381393 proxyDelegate. cancel ( for: authorizationPerformer. uniqueIdentifier)
382394 } )
383395 }
384396}
397+
398+ extension CLAuthorizationStatus : CustomStringConvertible {
399+ public var description : String {
400+ switch self {
401+ case . notDetermined: return " .notDetermined "
402+ case . restricted: return " .restricted "
403+ case . denied: return " .denied "
404+ case . authorizedWhenInUse: return " .authorizedWhenInUse "
405+ case . authorizedAlways: return " .authorisedAlways "
406+ @unknown default : return " unknown \( rawValue) "
407+ }
408+ }
409+ }
410+
411+ extension CLAccuracyAuthorization : CustomStringConvertible {
412+ public var description : String {
413+ switch self {
414+ case . fullAccuracy: return " .fullAccuracy "
415+ case . reducedAccuracy: return " .reducedAccuracy "
416+ @unknown default : return " unknown \( rawValue) "
417+ }
418+ }
419+ }
420+
0 commit comments