diff --git a/Xamarin.Essentials/Permissions/Permissions.ios.tvos.watchos.cs b/Xamarin.Essentials/Permissions/Permissions.ios.tvos.watchos.cs index 244c3f307..7404a05bd 100644 --- a/Xamarin.Essentials/Permissions/Permissions.ios.tvos.watchos.cs +++ b/Xamarin.Essentials/Permissions/Permissions.ios.tvos.watchos.cs @@ -136,12 +136,13 @@ internal static Task RequestLocationAsync(bool whenInUse, Acti return Task.FromResult(PermissionStatus.Disabled); locationManager = new CLLocationManager(); + var previousState = locationManager.GetAuthorizationStatus(); var tcs = new TaskCompletionSource(locationManager); - var previousState = CLLocationManager.Status; - - locationManager.AuthorizationChanged += LocationAuthCallback; + var del = new ManagerDelegate(); + del.AuthorizationStatusChanged += LocationAuthCallback; + locationManager.Delegate = del; invokeRequest(locationManager); @@ -165,7 +166,7 @@ void LocationAuthCallback(object sender, CLAuthorizationChangedEventArgs e) // Wait for a timeout to see if the check is complete if (tcs != null && !tcs.Task.IsCompleted) { - locationManager.AuthorizationChanged -= LocationAuthCallback; + del.AuthorizationStatusChanged -= LocationAuthCallback; tcs.TrySetResult(GetLocationStatus(whenInUse)); } } @@ -184,8 +185,7 @@ void LocationAuthCallback(object sender, CLAuthorizationChangedEventArgs e) } } - locationManager.AuthorizationChanged -= LocationAuthCallback; - + del.AuthorizationStatusChanged -= LocationAuthCallback; tcs.TrySetResult(GetLocationStatus(whenInUse)); locationManager?.Dispose(); locationManager = null; @@ -199,6 +199,19 @@ void LocationAuthCallback(object sender, CLAuthorizationChangedEventArgs e) } } } + + class ManagerDelegate : NSObject, ICLLocationManagerDelegate + { + public event EventHandler AuthorizationStatusChanged; + + [Export("locationManager:didChangeAuthorizationStatus:")] + public void AuthorizationChanged(CLLocationManager manager, CLAuthorizationStatus status) => + AuthorizationStatusChanged?.Invoke(this, new CLAuthorizationChangedEventArgs(status)); + + [Export("locationManagerDidChangeAuthorization:")] + public void DidChangeAuthorization(CLLocationManager manager) => + AuthorizationStatusChanged?.Invoke(this, new CLAuthorizationChangedEventArgs(manager.AuthorizationStatus)); + } } public partial class LocationAlways : BasePlatformPermission diff --git a/Xamarin.Essentials/Types/LocationExtensions.ios.tvos.watchos.macos.cs b/Xamarin.Essentials/Types/LocationExtensions.ios.tvos.watchos.macos.cs index 2aefea3ca..80355b6df 100644 --- a/Xamarin.Essentials/Types/LocationExtensions.ios.tvos.watchos.macos.cs +++ b/Xamarin.Essentials/Types/LocationExtensions.ios.tvos.watchos.macos.cs @@ -49,5 +49,20 @@ internal static DateTimeOffset ToDateTime(this NSDate timestamp) return DateTimeOffset.UtcNow; } } + + internal static CLAuthorizationStatus GetAuthorizationStatus(this CLLocationManager locationManager) + { +#if !__MACOS__ // this is coming in macOS 11 +#if __WATCHOS__ + if (Platform.HasOSVersion(7, 0)) +#else + if (Platform.HasOSVersion(14, 0)) +#endif + return locationManager.AuthorizationStatus; + +#endif + + return CLLocationManager.Status; + } } }