Skip to content

[iOS] Resolving Trimming Warnings for dotnet new maui #19397

@simonrozsival

Description

@simonrozsival

Trimming unused code from libraries used in an application is crucial to minimize deployment size. One of our goals for .NET 9 is to make MAUI trimming-friendly (#18658).

Publishing the base MAUI app dotnet new maui for iOS with NativeAOT currently emits 69 warnings (64 Trim analysis warnings + 5 AOT analysis warnings). Our first goal is to make the codepaths used in the base MAUI app trimming and AOT friendly (0 warnings).

Once the template MAUI app is warning-free, we will move onto more complex scenarios (possibly WeatherTwentyOne or eShop ClientApp).

Build steps

  1. create new MAUI project
./bin/dotnet/dotnet new maui -o TestApp && cd TestApp && dotnet restore
  1. build for iOS with NativeAOT
./bin/dotnet/dotnet publish \
  -f net8.0-ios \
  -r ios-arm64 \
  -p:PublishAot=true \
  -p:PublishAotUsingRuntimePack=true \
  -p:_RequireCodeSigning=false \
  -p:EnableTrimAnalyzer=true \
  -p:TrimmerSingleWarn=false | tee TestApp.log
  1. count warnings
grep -c 'Trim analysis warning\|AOT analysis warning' TestApp.log

Warnings (grouped by class or namespace)

  • Microsoft.Maui.Controls.BindableProperty - 1
  • Microsoft.Maui.Controls.BindablePropertyConverter - 1
  • Microsoft.Maui.HotReload.MauiHotReloadHelper - 2
    • fixed in [Trimming] Fix several trimming warnings #19402
    • Invokes System.Activator.CreateInstance(Type,Object[]) without a DynamicallyAccessedMemberTypes.PublicConstructors type
    • Invokes System.Activator.CreateInstance(Type) without a DynamicallyAccessedMemberTypes.PublicParameterlessConstructor type
  • Microsoft.Maui.Controls.DependencyService - 1
  • Microsoft.Maui.Controls.ResourceDictionary - 1
  • Microsoft.Maui.Controls.Routing - 1
  • Microsoft.Maui.Controls.ShellContent - 2
  • Microsoft.Maui.Controls.VisualTypeConverter - 2
    • fixed in [Trimming] Disable assembly scanning for types implementing IVisual #20417
    • Invokes System.Reflection.Assembly.GetExportedTypes() from an overridden ConvertFrom(ITypeDescriptorContext,CultureInfo,object) and ConvertTo(ITypeDescriptorContext,CultureInfo,object,Type) which aren't decorated with RequiresUnreferencedCodeAttribute
    • Type from System.Reflection.Assembly.GetExportedTypes() is not decorated with DynamicallAccessedMemberTypes.PublicParameterlessConstructor
  • Microsoft.Maui.Controls.Xaml.TypeConversionExtensions - 2
  • Microsoft.Maui.Controls.Xaml.TypeConversionExtensions - 4
    • fixed in [Trimming] Fix several trimming warnings #19402
    • Unrecognized value passed to the parameter typeName of method System.Type.GetType(String)
    • Invokes System.Activator.CreateInstance(Type) without a DynamicallyAccessedMemberTypes.PublicParameterlessConstructor type.
  • Microsoft.Maui.Controls.Xaml.ApplyPropertiesVisitor - 18
    • fixed in [Trimming] Add a feature flag to disable XAML loading at runtime #19310
    • Invokes System.Reflection.RuntimeReflectionExtensions.GetRuntimeEvents(Type) with a Type not decorated with DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents
    • Invokes System.Reflection.RuntimeReflectionExtensions.GetRuntimeEvent(Type,String) with a String not decorated with DynamicallyAccessedMemberTypes.PublicEvents
    • Invokes System.Reflection.RuntimeReflectionExtensions.GetRuntimeMethods(Type) for a type not decorated with DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods
    • Invokes System.Reflection.RuntimeReflectionExtensions.GetRuntimeProperties(Type) with a Type not decorated with DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties
    • Invokes System.Type.GetFields(BindingFlags) with a Type not decorated with DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFieldsInvokes
    • Invokes System.Type.GetInterfaces() with a Type not decorated with DynamicallyAccessedMemberTypes.Interfaces
    • Invokes System.Type.GetMethod(String,BindingFlags) with a Type not decorated with DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods
    • Invokes System.Type.GetProperty(String,BindingFlags) with a Type not decorated with DynamicallyAccessedMemberTypes.PublicProperties
  • Microsoft.Maui.Controls.Xaml.CreateValuesVisitor - 8
    • fixed in [Trimming] Add a feature flag to disable XAML loading at runtime #19310
    • Invokes System.Activator.CreateInstance(Type) with a Type not decorated with DynamicallyAccessedMemberTypes.PublicParameterlessConstructor
    • Invokes System.Activator.CreateInstance(Type,Object[]) with a Type not decorated with DynamicallyAccessedMemberTypes.PublicConstructors
    • Invokes System.Reflection.TypeInfo.DeclaredConstructors.get with a TypeInfo not decorated with DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors
    • Invokes System.Reflection.RuntimeReflectionExtensions.GetRuntimeMethods(Type) with a Type not decorated with DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods
  • Microsoft.Maui.Controls.Xaml.MarkupExpressionParser - 1
  • Microsoft.Maui.Controls.Xaml.XamlParser - 3
  • Microsoft.Maui.Hosting.ImageSourceServiceProvider - 7
  • Microsoft.Maui.Hosting.Internal.MauiFactory - 4
  • Microsoft.Maui.Platform.ReflectionExtensions - 1
  • Microsoft.Maui.Controls.BindingExpression - 9
    • solution proposed in [Trimming] Use typed bindings internally #20567
    • Invokes System.Reflection APIs (DeclaredProperties.get, ImplementedInterfaces.get, GetDeclaredMethod(String), GetDeclaredProperty(String) GetDeclaredField(String)) with a TypeInfo not decorated with DynamicallyAccessedMemberTypes
  • <Module>..cctor() - 1

Automated testing

There is a test that counts the warnings in the MAUI app (introduced in #19194). PRs which fix any of the warnings should update the list of expected warnings.

/cc @jonathanpeppers @mdh1418 @ivanpovazan

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions