Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AVMetadataObjectType enumeration fails on iOS 17 #18833

Closed
Cheesebaron opened this issue Aug 25, 2023 · 2 comments · Fixed by #18925
Closed

AVMetadataObjectType enumeration fails on iOS 17 #18833

Cheesebaron opened this issue Aug 25, 2023 · 2 comments · Fixed by #18925
Labels
bug If an issue is a bug or a pull request a bug fix
Milestone

Comments

@Cheesebaron
Copy link

Steps to Reproduce

  1. Run app on iOS 17 beta with below code
var availableTypes = _metadataOutput.AvailableMetadataObjectTypes;
if (availableTypes.HasFlag(AVMetadataObjectType.QRCode))

Expected Behavior

App should not crash

Actual Behavior

App crashes with NotSupportedException humanFullBody has no associated enum value on this platform due to a new value Apple added to AVMetadataObjectType called humanFullBody which isn't bound.

Environment

Version information
.NET SDK:
 Version:   7.0.400
 Commit:    73bf45718d

Runtime Environment:
 OS Name:     Mac OS X
 OS Version:  13.5
 OS Platform: Darwin
 RID:         osx.13-arm64
 Base Path:   /usr/local/share/dotnet/sdk/7.0.400/

Host:
  Version:      7.0.10
  Architecture: arm64
  Commit:       a6dbb800a4

.NET SDKs installed:
  7.0.400 [/usr/local/share/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 7.0.10 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 7.0.10 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
  x64   [/usr/local/share/dotnet/x64]
    registered at [/etc/dotnet/install_location_x64]

Environment variables:
  Not set

global.json file:
  /Users/tomaszcielecki/git/DrivingRangeApp/global.json

Xcode 14.3.1

Installed Workload Id      Manifest Version       Installation Source
---------------------------------------------------------------------
macos                      13.3.7090/7.0.100      SDK 7.0.400
maui-ios                   7.0.92/7.0.100         SDK 7.0.400
maui-android               7.0.92/7.0.100         SDK 7.0.400
ios                        16.4.7090/7.0.100      SDK 7.0.400
maccatalyst                16.4.7090/7.0.100      SDK 7.0.400
tvos                       16.4.7090/7.0.100      SDK 7.0.400
android                    33.0.68/7.0.100        SDK 7.0.400

Build Logs

Example Project (If Possible)

@rolfbjarne
Copy link
Member

This comes from here:

get { return AVMetadataObject.ArrayToEnum (WeakAvailableMetadataObjectTypes); }

and then:

internal static AVMetadataObjectType ArrayToEnum (NSString[]? arr)
{
AVMetadataObjectType rv = AVMetadataObjectType.None;
if (arr is null || arr.Length == 0)
return rv;
foreach (var str in arr) {
rv |= AVMetadataObjectTypeExtensions.GetValue (str);
}
return rv;
}

We should probably change the latter to not throw an exception if any elements in the array can't be converted to an enum value.

The main problem is that this may break existing apps when the OS upgrades, if the code can't cope correctly with new elements in the array coming from the OS.

@rolfbjarne rolfbjarne added this to the .NET 8 milestone Aug 25, 2023
@rolfbjarne rolfbjarne added the bug If an issue is a bug or a pull request a bug fix label Aug 25, 2023
rolfbjarne added a commit to rolfbjarne/xamarin-macios that referenced this issue Sep 5, 2023
…Flags] enums.

We have a few different implementations of how to compute a set or array of NSString
constants from an enum value, and also computing an enum value from a set or array
of NSString constants.

So add support to the generator for generating a ToArray and a ToFlags method for
these conversions, and remove all the manual code.

This has a few advantages:

* The generated code is automatically updated with new enum fields (not all previous
  implementations were).
* Reduces code duplication.
* Reduces manual code.

Additionally, when computing between a group of constants and the corresponding flags,
we have to handle any missing constants or flags gracefully, otherwise the code won’t
be forward compatible.

Example (from bug xamarin#18833):

* App developer writes code to fetch the AVCaptureMetadataOutput.AvailableMetadataObjectTypes
  property, which is an enum value of flags.
* App developer ships their app in the app store.
* Apple releases a new iOS update, adding new values and constants to the enum.
* The native [AVCaptureMetadataOutput availableMetadataObjectTypes] method returns
  these new constants.
* This means that if the AVCaptureMetadataOutput.AvailableMetadataObjectTypes property
  throws an exception if encountering unknown constants, our API wouldn’t be forward
  compatible.
* The correct solution here is that AVCaptureMetadataOutput.AvailableMetadataObjectTypes
  must ignore any constants it doesn’t know about.

Fixes xamarin#18833.
rolfbjarne added a commit that referenced this issue Sep 6, 2023
…Flags] enums. (#18925)

We have a few different implementations of how to compute a set or array of NSString
constants from an enum value, and also computing an enum value from a set or array
of NSString constants.

So add support to the generator for generating a ToArray and a ToFlags method for
these conversions, and remove all the manual code.

This has a few advantages:

* The generated code is automatically updated with new enum fields (not all previous
  implementations were).
* Reduces code duplication.
* Reduces manual code.

Additionally, when computing between a group of constants and the corresponding flags,
we have to handle any missing constants or flags gracefully, otherwise the code won’t
be forward compatible.

Example (from bug #18833):

* App developer writes code to fetch the AVCaptureMetadataOutput.AvailableMetadataObjectTypes
  property, which is an enum value of flags.
* App developer ships their app in the app store.
* Apple releases a new iOS update, adding new values and constants to the enum.
* The native [AVCaptureMetadataOutput availableMetadataObjectTypes] method returns
  these new constants.
* This means that if the AVCaptureMetadataOutput.AvailableMetadataObjectTypes property
  throws an exception if encountering unknown constants, our API wouldn’t be forward
  compatible.
* The correct solution here is that AVCaptureMetadataOutput.AvailableMetadataObjectTypes
  must ignore any constants it doesn’t know about.

Fixes #18833.
@Glorfindel83
Copy link

I'm still having this problem (humanFullBody has no associated enum value on this platform) with the latest version of Xamarin.iOS (16.4.0.23) on an iPhone 13 running iOS 17.5.1 and a brand new iPad Air running iOS 18 public beta, but not on an older iPad running iOS 17.4.1. Do the AVMetadataObjectType values differ per device model as well?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug If an issue is a bug or a pull request a bug fix
Projects
None yet
3 participants