From 4536bbffde0edf079c988d9c88ae363c84019ad8 Mon Sep 17 00:00:00 2001 From: Jakub Florkowski Date: Mon, 21 Jul 2025 01:40:44 +0200 Subject: [PATCH 1/3] [iOS] Permissions.RequestAsync does not return a value on iOS16+ --- .../Permissions/Permissions.ios.watchos.cs | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/Essentials/src/Permissions/Permissions.ios.watchos.cs b/src/Essentials/src/Permissions/Permissions.ios.watchos.cs index ba5053d3b63a..ab70c008383f 100644 --- a/src/Essentials/src/Permissions/Permissions.ios.watchos.cs +++ b/src/Essentials/src/Permissions/Permissions.ios.watchos.cs @@ -199,19 +199,7 @@ internal static PermissionStatus GetSensorPermissionStatus() if (OperatingSystem.IsIOSVersionAtLeast(11, 0) || OperatingSystem.IsWatchOSVersionAtLeast(4, 0)) { -#pragma warning disable CA1416 // https://github.com/xamarin/xamarin-macios/issues/14619 - switch (CMMotionActivityManager.AuthorizationStatus) - { - case CMAuthorizationStatus.Authorized: - return PermissionStatus.Granted; - case CMAuthorizationStatus.Denied: - return PermissionStatus.Denied; - case CMAuthorizationStatus.NotDetermined: - return PermissionStatus.Unknown; - case CMAuthorizationStatus.Restricted: - return PermissionStatus.Restricted; - } -#pragma warning restore CA1416 + return ConvertAuthorizationStatus(CMMotionActivityManager.AuthorizationStatus); } return PermissionStatus.Unknown; @@ -230,11 +218,24 @@ internal static async Task RequestSensorPermission() catch (Exception ex) { Debug.WriteLine("Unable to query activity manager: " + ex.Message); - return PermissionStatus.Denied; + // Fall back to checking the authorization status directly + return ConvertAuthorizationStatus(CMMotionActivityManager.AuthorizationStatus); } return PermissionStatus.Unknown; } + + private static PermissionStatus ConvertAuthorizationStatus(CMAuthorizationStatus status) + { + return status switch + { + CMAuthorizationStatus.Authorized => PermissionStatus.Granted, + CMAuthorizationStatus.Denied => PermissionStatus.Denied, + CMAuthorizationStatus.NotDetermined => PermissionStatus.Unknown, + CMAuthorizationStatus.Restricted => PermissionStatus.Restricted, + _ => PermissionStatus.Unknown, + }; + } } public partial class LocationAlways : BasePlatformPermission From 621b68809cd419e7523fa069641a5c846316c5af Mon Sep 17 00:00:00 2001 From: Jakub Florkowski Date: Tue, 22 Jul 2025 00:54:11 +0200 Subject: [PATCH 2/3] Update Permissions.ios.watchos.cs --- .../src/Permissions/Permissions.ios.watchos.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Essentials/src/Permissions/Permissions.ios.watchos.cs b/src/Essentials/src/Permissions/Permissions.ios.watchos.cs index ab70c008383f..abe2187deeeb 100644 --- a/src/Essentials/src/Permissions/Permissions.ios.watchos.cs +++ b/src/Essentials/src/Permissions/Permissions.ios.watchos.cs @@ -218,7 +218,15 @@ internal static async Task RequestSensorPermission() catch (Exception ex) { Debug.WriteLine("Unable to query activity manager: " + ex.Message); - // Fall back to checking the authorization status directly + // Fall back to checking the authorization status directly when QueryActivityAsync fails. + // This can happen for several reasons: + // 1. Motion & Fitness permission has been denied by the user + // 2. The device doesn't support motion activity tracking (rare but possible) + // 3. System restrictions prevent access to motion data + // 4. Network or system errors during the query operation + // By falling back to AuthorizationStatus, we can still provide accurate permission + // state information even when the query method fails, ensuring the permission + // request flow completes properly and returns the correct PermissionStatus. return ConvertAuthorizationStatus(CMMotionActivityManager.AuthorizationStatus); } From 5f0e43c13932a471f14981478cbe2bf1354434fe Mon Sep 17 00:00:00 2001 From: Jakub Florkowski Date: Thu, 24 Jul 2025 01:55:29 +0200 Subject: [PATCH 3/3] Catching a specific error --- src/Essentials/src/Permissions/Permissions.ios.watchos.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Essentials/src/Permissions/Permissions.ios.watchos.cs b/src/Essentials/src/Permissions/Permissions.ios.watchos.cs index abe2187deeeb..3ea065f0cf37 100644 --- a/src/Essentials/src/Permissions/Permissions.ios.watchos.cs +++ b/src/Essentials/src/Permissions/Permissions.ios.watchos.cs @@ -215,9 +215,8 @@ internal static async Task RequestSensorPermission() if (results != null) return PermissionStatus.Granted; } - catch (Exception ex) + catch (NSErrorException) { - Debug.WriteLine("Unable to query activity manager: " + ex.Message); // Fall back to checking the authorization status directly when QueryActivityAsync fails. // This can happen for several reasons: // 1. Motion & Fitness permission has been denied by the user @@ -229,6 +228,11 @@ internal static async Task RequestSensorPermission() // request flow completes properly and returns the correct PermissionStatus. return ConvertAuthorizationStatus(CMMotionActivityManager.AuthorizationStatus); } + catch (Exception ex) + { + Debug.WriteLine("Unable to query activity manager: " + ex.Message); + return PermissionStatus.Denied; + } return PermissionStatus.Unknown; }