From c3a3f31666d1637a1f5ef0c2b00d843961d903cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Sj=C3=B6gren?= Date: Fri, 6 Nov 2020 01:54:46 +0100 Subject: [PATCH] Handle new iOS location permission event (issue 1390) (#1487) Co-authored-by: Matthew Leibowitz --- .../Permissions.ios.tvos.watchos.cs | 25 ++++++++++++++----- ...cationExtensions.ios.tvos.watchos.macos.cs | 15 +++++++++++ 2 files changed, 34 insertions(+), 6 deletions(-) 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; + } } }