Skip to content

Commit

Permalink
[Essentials] Fix maciOS version checks
Browse files Browse the repository at this point in the history
Commit 158ffbd accidentially introduced what was likely a breaking
change in `Platform.ios.tvos.watchos.HasOSVersion`.  The call to
`UIDevice.CurrentDevice.CheckSystemVersion` was replaced by
`OperatingSystem.IsIOSVersionAtLeast`, however `HasOSVersion` was used
on platforms other than iOS.

Fix this oversight by removing `HasOSVersion` entirely, and use the
correct `Is$(Platform)VersionAtLeast` variant at all call sites instead.

`OperatingSystem.IsIOSVersionAtLeast` will work on iOS and MacCatalyst,
but not on tvOS. Additional tvOS checks have been added as needed.

Instances of `DeviceInfo.Version` have also been replaced by
`Is$(Platform)VersionAtLeast` where applicable.
  • Loading branch information
pjcollins committed Feb 25, 2022
1 parent 2b568a4 commit 2ca2834
Show file tree
Hide file tree
Showing 21 changed files with 41 additions and 78 deletions.
10 changes: 5 additions & 5 deletions src/Compatibility/Core/src/iOS/Forms.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ internal static bool IsiOS11OrNewer
get
{
if (!s_isiOS11OrNewer.HasValue)
s_isiOS11OrNewer = OperatingSystem.IsIOSVersionAtLeast(11, 0);
s_isiOS11OrNewer = OperatingSystem.IsIOSVersionAtLeast(11, 0) || OperatingSystem.IsTvOSVersionAtLeast(11, 0);
return s_isiOS11OrNewer.Value;
}
}
Expand All @@ -65,7 +65,7 @@ internal static bool IsiOS12OrNewer
get
{
if (!s_isiOS12OrNewer.HasValue)
s_isiOS12OrNewer = OperatingSystem.IsIOSVersionAtLeast(12, 0);
s_isiOS12OrNewer = OperatingSystem.IsIOSVersionAtLeast(12, 0) || OperatingSystem.IsTvOSVersionAtLeast(12, 0);
return s_isiOS12OrNewer.Value;
}
}
Expand All @@ -75,7 +75,7 @@ internal static bool IsiOS13OrNewer
get
{
if (!s_isiOS13OrNewer.HasValue)
s_isiOS13OrNewer = OperatingSystem.IsIOSVersionAtLeast(13, 0);
s_isiOS13OrNewer = OperatingSystem.IsIOSVersionAtLeast(13, 0) || OperatingSystem.IsTvOSVersionAtLeast(13, 0);
return s_isiOS13OrNewer.Value;
}
}
Expand All @@ -85,7 +85,7 @@ internal static bool IsiOS14OrNewer
get
{
if (!s_isiOS14OrNewer.HasValue)
s_isiOS14OrNewer = OperatingSystem.IsIOSVersionAtLeast(14, 0);
s_isiOS14OrNewer = OperatingSystem.IsIOSVersionAtLeast(14, 0) || OperatingSystem.IsTvOSVersionAtLeast(14, 0);
return s_isiOS14OrNewer.Value;
}
}
Expand All @@ -95,7 +95,7 @@ internal static bool IsiOS15OrNewer
get
{
if (!s_isiOS15OrNewer.HasValue)
s_isiOS15OrNewer = OperatingSystem.IsIOSVersionAtLeast(15, 0);
s_isiOS15OrNewer = OperatingSystem.IsIOSVersionAtLeast(15, 0) || OperatingSystem.IsTvOSVersionAtLeast(15, 0);
return s_isiOS15OrNewer.Value;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Core/src/Platform/iOS/ElementExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public static UIViewController ToUIViewController(this IElement view, IMauiConte
// If < iOS 13 or the Info.plist does not have a scene manifest entry we need to assume no multi window, and no UISceneDelegate.
// We cannot check for iPads/Mac because even on the iPhone it uses the scene delegate if one is specified in the manifest.
public static bool HasSceneManifest(this IUIApplicationDelegate platformApplication) =>
OperatingSystem.IsIOSVersionAtLeast(13, 0) &&
(OperatingSystem.IsIOSVersionAtLeast(13, 0) || OperatingSystem.IsTvOSVersionAtLeast(13,0)) &&
NSBundle.MainBundle.InfoDictionary.ContainsKey(new NSString(UIApplicationSceneManifestKey));
}
}
2 changes: 1 addition & 1 deletion src/Core/src/Platform/iOS/PlatformVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public static class PlatformVersion
{
public static bool IsAtLeast(int version)
{
return OperatingSystem.IsIOSVersionAtLeast(version);
return OperatingSystem.IsIOSVersionAtLeast(version) || OperatingSystem.IsTvOSVersionAtLeast(version);
}

private static bool? SetNeedsUpdateOfHomeIndicatorAutoHidden;
Expand Down
2 changes: 1 addition & 1 deletion src/Essentials/src/AppActions/AppActions.ios.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public partial class AppActionsImplementation : IAppActions
public string Type => "XE_APP_ACTION_TYPE";

public bool IsSupported
=> Platform.HasOSVersion(9, 0);
=> true;

public Task<IEnumerable<AppAction>> GetAsync()
{
Expand Down
4 changes: 2 additions & 2 deletions src/Essentials/src/AppInfo/AppInfo.ios.tvos.watchos.macos.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public AppTheme RequestedTheme
{
get
{
if (!Platform.HasOSVersion(13, 0))
if ((OperatingSystem.IsIOS() && !OperatingSystem.IsIOSVersionAtLeast(13, 0)) || (OperatingSystem.IsTvOS() && !OperatingSystem.IsTvOSVersionAtLeast(13, 0)))
return AppTheme.Unspecified;

var uiStyle = Platform.GetCurrentUIViewController()?.TraitCollection?.UserInterfaceStyle ??
Expand All @@ -70,7 +70,7 @@ public AppTheme RequestedTheme
{
get
{
if (DeviceInfo.Version >= new Version(10, 14))
if (OperatingSystem.IsMacOSVersionAtLeast(10, 14))
{
var app = NSAppearance.CurrentAppearance?.FindBestMatch(new string[]
{
Expand Down
2 changes: 1 addition & 1 deletion src/Essentials/src/DeviceDisplay/DeviceDisplay.ios.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public DisplayInfo GetMainDisplayInfo()
density: scale,
orientation: CalculateOrientation(),
rotation: CalculateRotation(),
rate: Platform.HasOSVersion(10, 3) ? UIScreen.MainScreen.MaximumFramesPerSecond : 0);
rate: (OperatingSystem.IsIOSVersionAtLeast(10, 3) || OperatingSystem.IsTvOSVersionAtLeast(10, 3)) ? UIScreen.MainScreen.MaximumFramesPerSecond : 0);
}

public void StartScreenMetricsListeners()
Expand Down
2 changes: 1 addition & 1 deletion src/Essentials/src/FilePicker/FilePicker.ios.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static async Task<IEnumerable<FileResult>> PlatformPickAsync(PickOptions options
// Use Open instead of Import so that we can attempt to use the original file.
// If the file is from an external provider, then it will be downloaded.
using var documentPicker = new UIDocumentPickerViewController(allowedUtis, UIDocumentPickerMode.Open);
if (Platform.HasOSVersion(11, 0))
if (OperatingSystem.IsIOSVersionAtLeast(11, 0))
documentPicker.AllowsMultipleSelection = allowMultiple;
documentPicker.Delegate = new PickerDelegate
{
Expand Down
22 changes: 8 additions & 14 deletions src/Essentials/src/HapticFeedback/HapticFeedback.ios.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,18 @@ public void Perform(HapticFeedbackType type)

void Click()
{
if (Platform.HasOSVersion(10, 0))
{
var impact = new UIImpactFeedbackGenerator(UIImpactFeedbackStyle.Light);
impact.Prepare();
impact.ImpactOccurred();
impact.Dispose();
}
var impact = new UIImpactFeedbackGenerator(UIImpactFeedbackStyle.Light);
impact.Prepare();
impact.ImpactOccurred();
impact.Dispose();
}

public void LongPress()
{
if (Platform.HasOSVersion(10, 0))
{
var impact = new UIImpactFeedbackGenerator(UIImpactFeedbackStyle.Medium);
impact.Prepare();
impact.ImpactOccurred();
impact.Dispose();
}
var impact = new UIImpactFeedbackGenerator(UIImpactFeedbackStyle.Medium);
impact.Prepare();
impact.ImpactOccurred();
impact.Dispose();
}
}
}
4 changes: 1 addition & 3 deletions src/Essentials/src/Launcher/Launcher.ios.tvos.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ Task<bool> PlatformOpenAsync(Uri uri) =>
PlatformOpenAsync(WebUtils.GetNativeUrl(uri));

Task<bool> PlatformOpenAsync(NSUrl nativeUrl) =>
Platform.HasOSVersion(10, 0)
? UIApplication.SharedApplication.OpenUrlAsync(nativeUrl, new UIApplicationOpenUrlOptions())
: Task.FromResult(UIApplication.SharedApplication.OpenUrl(nativeUrl));
UIApplication.SharedApplication.OpenUrlAsync(nativeUrl, new UIApplicationOpenUrlOptions());

Task<bool> PlatformTryOpenAsync(Uri uri)
{
Expand Down
12 changes: 3 additions & 9 deletions src/Essentials/src/MediaPicker/MediaPicker.ios.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public async Task<FileResult> PhotoAsync(MediaPickerOptions options, bool photo,
await Permissions.EnsureGrantedAsync<Permissions.Microphone>();

// Check if picking existing or not and ensure permission accordingly as they can be set independently from each other
if (pickExisting && !Platform.HasOSVersion(11, 0))
if (pickExisting && !OperatingSystem.IsIOSVersionAtLeast(11, 0))
await Permissions.EnsureGrantedAsync<Permissions.Photos>();

if (!pickExisting)
Expand Down Expand Up @@ -109,7 +109,7 @@ static FileResult DictionaryToMediaFile(NSDictionary info)
PHAsset phAsset = null;
NSUrl assetUrl = null;

if (Platform.HasOSVersion(11, 0))
if (OperatingSystem.IsIOSVersionAtLeast(11, 0))
{
assetUrl = info[UIImagePickerController.ImageUrl] as NSUrl;

Expand Down Expand Up @@ -147,13 +147,7 @@ static FileResult DictionaryToMediaFile(NSDictionary info)
if (phAsset == null || assetUrl == null)
return null;

string originalFilename;

if (Platform.HasOSVersion(9, 0))
originalFilename = PHAssetResource.GetAssetResources(phAsset).FirstOrDefault()?.OriginalFilename;
else
originalFilename = phAsset.ValueForKey(new NSString("filename")) as NSString;

string originalFilename = PHAssetResource.GetAssetResources(phAsset).FirstOrDefault()?.OriginalFilename;
return new PHAssetFileResult(assetUrl, phAsset, originalFilename);
}

Expand Down
11 changes: 0 additions & 11 deletions src/Essentials/src/Permissions/Permissions.ios.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,6 @@ public override Task<PermissionStatus> RequestAsync()

internal static PermissionStatus GetMediaPermissionStatus()
{
// Only available in 9.3+
if (!Platform.HasOSVersion(9, 3))
return PermissionStatus.Unknown;

var status = MPMediaLibrary.AuthorizationStatus;
return status switch
{
Expand All @@ -184,10 +180,6 @@ internal static PermissionStatus GetMediaPermissionStatus()

internal static Task<PermissionStatus> RequestMediaPermission()
{
// Only available in 9.3+
if (!Platform.HasOSVersion(9, 3))
return Task.FromResult(PermissionStatus.Unknown);

var tcs = new TaskCompletionSource<PermissionStatus>();

MPMediaLibrary.RequestAuthorization(s =>
Expand Down Expand Up @@ -278,9 +270,6 @@ internal static PermissionStatus GetSpeechPermissionStatus()

internal static Task<PermissionStatus> RequestSpeechPermission()
{
if (!Platform.HasOSVersion(10, 0))
return Task.FromResult(PermissionStatus.Unknown);

var tcs = new TaskCompletionSource<PermissionStatus>();

SFSpeechRecognizer.RequestAuthorization(s =>
Expand Down
11 changes: 5 additions & 6 deletions src/Essentials/src/Permissions/Permissions.ios.tvos.macos.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,10 @@ static PermissionStatus Convert(PHAuthorizationStatus status)
};

static bool CheckOSVersionForPhotos()
#if __MACOS__
=> Platform.HasOSVersion(11, 0);
#else
=> Platform.HasOSVersion(14, 0);
#endif

{
return OperatingSystem.IsIOSVersionAtLeast(14, 0) ||
OperatingSystem.IsMacOSVersionAtLeast(11, 0) ||
OperatingSystem.IsTvOSVersionAtLeast(14, 0);
}
}
}
2 changes: 1 addition & 1 deletion src/Essentials/src/Permissions/Permissions.ios.watchos.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ internal static PermissionStatus GetSensorPermissionStatus()
if (!CMMotionActivityManager.IsActivityAvailable)
return PermissionStatus.Disabled;

if (Platform.HasOSVersion(11, 0))
if (OperatingSystem.IsIOSVersionAtLeast(11, 0) || OperatingSystem.IsWatchOSVersionAtLeast(4, 0))
{
switch (CMMotionActivityManager.AuthorizationStatus)
{
Expand Down
3 changes: 0 additions & 3 deletions src/Essentials/src/Platform/Platform.ios.tvos.watchos.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,6 @@ internal static string GetSystemLibraryProperty(string property)
return returnValue;
}

internal static bool HasOSVersion(int major, int minor) =>
OperatingSystem.IsIOSVersionAtLeast(major, minor);

#if __IOS__ || __TVOS__

static Func<UIViewController> getCurrentController;
Expand Down
6 changes: 0 additions & 6 deletions src/Essentials/src/Platform/Platform.macos.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,6 @@ internal static NSWindow GetCurrentWindow(bool throwIfNull = true)

return window;
}

internal static bool HasOSVersion(int major, int minor)
{
using var info = new NSProcessInfo();
return info.IsOperatingSystemAtLeastVersion(new NSOperatingSystemVersion(major, minor, 0));
}
}

internal static class CoreGraphicsInterop
Expand Down
5 changes: 3 additions & 2 deletions src/Essentials/src/Share/Share.ios.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Foundation;
Expand Down Expand Up @@ -31,7 +32,7 @@ public Task RequestAsync(ShareTextRequest request)
{
activityController.PopoverPresentationController.SourceView = vc.View;

if (request.PresentationSourceBounds != Rectangle.Zero || Platform.HasOSVersion(13, 0))
if (request.PresentationSourceBounds != Rectangle.Zero || OperatingSystem.IsIOSVersionAtLeast(13, 0))
activityController.PopoverPresentationController.SourceRect = request.PresentationSourceBounds.AsCGRect();
}

Expand Down Expand Up @@ -60,7 +61,7 @@ public Task RequestAsync(ShareMultipleFilesRequest request)
{
activityController.PopoverPresentationController.SourceView = vc.View;

if (request.PresentationSourceBounds != Rectangle.Zero || Platform.HasOSVersion(13, 0))
if (request.PresentationSourceBounds != Rectangle.Zero || OperatingSystem.IsIOSVersionAtLeast(13, 0))
activityController.PopoverPresentationController.SourceRect = request.PresentationSourceBounds.AsCGRect();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,10 @@ internal static DateTimeOffset ToDateTime(this NSDate timestamp)

internal static CLAuthorizationStatus GetAuthorizationStatus(this CLLocationManager locationManager)
{
#if __MACOS__
if (DeviceInfo.Version >= new Version(11, 0))
#elif __WATCHOS__
if (Platform.HasOSVersion(7, 0))
#else
if (Platform.HasOSVersion(14, 0))
#endif
if (OperatingSystem.IsIOSVersionAtLeast(14, 0) ||
OperatingSystem.IsMacOSVersionAtLeast(11, 0) ||
OperatingSystem.IsWatchOSVersionAtLeast(7, 0) ||
OperatingSystem.IsTvOSVersionAtLeast(14, 0))
{
// return locationManager.AuthorizationStatus;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public partial class AppleSignInAuthenticatorImplementation : IAppleSignInAuthen

public async Task<WebAuthenticatorResult> AuthenticateAsync(AppleSignInAuthenticator.Options options)
{
if (DeviceInfo.Version.Major < 13)
if (!OperatingSystem.IsIOSVersionAtLeast(13))
throw new FeatureNotSupportedException();

var provider = new ASAuthorizationAppleIdProvider();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ public bool OpenUrlCallback(Uri uri)
static bool VerifyHasUrlSchemeOrDoesntRequire(string scheme)
{
// iOS11+ uses sfAuthenticationSession which handles its own url routing
if (OperatingSystem.IsIOSVersionAtLeast(11, 0))
if (OperatingSystem.IsIOSVersionAtLeast(11, 0) || OperatingSystem.IsTvOSVersionAtLeast (11, 0))
return true;

return AppInfoImplementation.VerifyHasUrlScheme(scheme);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public async Task<WebAuthenticatorResult> AuthenticateAsync(WebAuthenticatorOpti
redirectUri = callbackUrl;
var scheme = redirectUri.Scheme;

if (DeviceInfo.Version >= new Version(10, 15))
if (OperatingSystem.IsMacOSVersionAtLeast(10, 15))
{
static void AuthSessionCallback(NSUrl cbUrl, NSError error)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Essentials/test/DeviceTests/Tests/AppActions_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public void IsSupported()
#if __ANDROID__
expectSupported = OperatingSystem.IsAndroidVersionAtLeast(25);
#elif __IOS__
expectSupported = Platform.HasOSVersion(9, 0);
expectSupported = true;
#endif

Assert.Equal(expectSupported, AppActions.IsSupported);
Expand Down

0 comments on commit 2ca2834

Please sign in to comment.