@available(macOS 11.0, *) not working in macOS bundles

Hello,

We are trying to implement some macOS 11 (and iOS/tvOS 14) specific native functions in to our game. In order to support backwards compatibility, we are using:

if (@available(macOS 11.0, iOS 14.0, tvOS 14.0, *))

With some fallback code if that check fails.

On iOS and tvOS as an .mm plugin this works great, however when we build it in to a macOS bundle and access it that way it always return false on macOS 11+ when we target macOS 10.15 for the bundle.
Does @available not work in bundles or might there be something that we are missing? If it’s not available in bundles, what would be the best way to check macOS versions in runtime?

What version of the OS are you running that it returns false on?

Big Sur 11.2.1. However I’m fairly sure 11.0 and 11.1 also do the same.

If in xcode I set the bundle project to target 10.15, it returns false on 11.2.1. When I set the target to 11.0 it returns true, but then when I run it on 10.15.7 I get a DllNotFoundException. Which I expect.

Following up on this, I ran a test in a fresh Objective-C application that imports a bundle at runtime and invokes a function through Apple’s equivalent of a DLL import. Both the bundle and the application have been build with 10.15 as Deployment Target. The OS that the application runs on is 11 Beta (Big Sur). The @available check correctly detects that the OS version is 11: http://img.desu.link/?i=z5KW8IJCk1.png

I then imported the same bundle into our Unity project running on the same OS and invoked the same method from C# via an extern method with the DllImport attribute, but in that case @available check inside the bundle fails: http://img.desu.link/?i=DDZ9yCtG4V.png

Can you report a bug report so we could track this? I’m trying to dig in why that could happen but I was unsuccessful at recreating it yet. Out of curiosity, does checking for macOS 11.1 work instead? We have a few of those checks in the engine and they definitely work for us.

@Tautvydas-Zilys thank you for your reply.

I made a few bundles with different @available checks in it, and imported it into a Unity (2019.4.4f1) project on another machine that runs macOS 11.2.1. When calling the bundle methods, I got the following results:

@available(macOS 10.0, *): true
@available(macOS 11.0, *): false
@available(macOS 11.1, *): false

https://fogbugz.unity3d.com/default.asp?1317669_m4mhkndcfkugej0l

Thanks, we’ll take a look.

How did you build the .framework? Which version of Xcode did you use?

@Tautvydas-Zilys we are using Xcode version 12.5 beta.

The project is created from the ‘Bundle’ template in the macOS category in the ‘Create new Xcode project’ from the launcher. The macOS Deployment Target is set to 10.15 manually.

I’m seeing similar behaviour here, I have a @available for 11.0 failing when running on macOS 11.2.1, built in xcode 12.4. Looking forward to any updates!

Looks like macOS Big Sur reports its version as 10.16 if the application is linked against 10.15 or older SDK. Unity 2019.4 is built using macOS 10.14 SDK, and thus the check fails. This issue does not reproduce in Unity 2020.2.

You can use “if (@available(macOS 10.16))” instead if you want your plugin to work with Unity 2019.4.

See Big Sur is both 10.16 and 11.0 – it’s official – The Eclectic Light Company for more details about this.

2 Likes

@Tautvydas-Zilys I can confirm that that solved the issue for us. Thank you so much.

+1 Thanks!