Latihan
Laluan pembelajaran
Build mobile and desktop apps with .NET MAUI - Training
In this learning path, use C# and Visual Studio with .NET MAUI to create an app that runs across iOS, Android, and Windows.
Pelayar ini tidak lagi disokong.
Naik taraf kepada Microsoft Edge untuk memanfaatkan ciri, kemas kini keselamatan dan sokongan teknikal yang terkini.
Native AOT deployment produces a .NET Multi-platform App UI (.NET MAUI) app on iOS and Mac Catalyst that's been ahead-of-time (AOT) compiled to native code. Native AOT performs static program analysis, full trimming of your app, which is aggressive in removing code that's not statically referenced, and ahead-of-time code generation.
Publishing and deploying a Native AOT app produces the following benefits:
Native AOT will introduce limitations on usage of certain aspects of the .NET runtime, and should only be used in scenarios where app size and performance are important. It'll require you to adapt your apps to Native AOT requirements, which means ensuring that they are fully trimming and AOT compatible. For more information about Native AOT limitations, see Native AOT limitations.
When Native AOT deployment is enabled, the build system analyzes your code, and all its dependencies, to verify if it's suitable for full trimming and AOT compilation. If incompatibilities are detected, trimming and AOT warnings are produced. A single trimming or AOT warning means that the app isn't compatible with Native AOT deployment, and that it might not work correctly. Therefore, when building an app for Native AOT deployment you should review and correct all trimming and AOT warnings. Failure to do this may result in exceptions at runtime since necessary code could have been removed. If you suppress the warnings the AOT deployed app must be thoroughly tested to verify that functionality hasn't changed from the untrimmed app. For more information, see Introduction to trim warnings and Introduction to AOT warnings.
Nota
There may be cases where fixing trimming and AOT warnings isn't possible, such as when they occur for third-party libraries. In such cases, third-party libraries will need to be updated to become fully compatible.
Publishing and deployment a Native AOT app produces an app that's typically up to 2.5x smaller, and an app that starts up typically up to 2x faster. However, the exact performance benefits are dependent upon multiple factors which include the platform being used, the device on which the app is running, and the app itself.
Penting
The following charts show typical performance benefits of Native AOT deployment for a dotnet new maui
app on iOS and Mac Catalyst. However, the exact data is hardware dependent and may change in future releases.
The following chart shows app package size for a dotnet new maui
app on iOS and Mac Catalyst across different deployment models:
The preceding chart shows that, typically, Native AOT produces more than 2x smaller apps for both iOS and Mac Catalyst compared to the default deployment model.
The following chart shows average startup time, on specific hardware, for a dotnet new maui
app on iOS and Mac Catalyst on Mono and Native AOT deployment:
The preceding chart shows that Native AOT typically has up to 2x faster startup times on iOS devices and 1.2x faster startup time on Mac Catalyst, compared to Mono deployment.
The following chart shows the average build time, on specific hardware, for a dotnet new maui
app on iOS and Mac Catalyst across different deployment models:
The preceding chart shows that typically Native AOT has up to 2.8x faster build times on iOS devices compared to the default deployment model. For Mac Catalyst, build times are comparable for arm64 single RID apps, but are slightly slower for universal apps when compared to Mono deployment.
Penting
In many scenarios Native AOT will produce smaller and faster apps. However, in some scenarios Native AOT might not produce smaller and faster apps. Therefore, it's important to test and profile your app to determine the result of enabling Native AOT deployment.
The Native AOT deployment model is enabled with the $(PublishAot)
build property, and the dotnet publish
command. The following example shows how to modify a project file to enable Native AOT deployment on iOS and Mac Catalyst:
<PropertyGroup>
<!-- enable trimming and AOT analyzers on all platforms -->
<IsAotCompatible>true</IsAotCompatible>
<!-- select platforms to use with NativeAOT -->
<PublishAot Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">true</PublishAot>
<PublishAot Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">true</PublishAot>
</PropertyGroup>
Setting the $(IsAotCompatible)
build property to true
, for all platforms, enables trimming and AOT analyzers. These analyzers help you identify code that's not compatible with trimming or AOT.
Conditionally setting $(PublishAot)
to true
, for iOS and Mac Catalyst, enables dynamic code usage analysis during build and Native AOT compilation during publish. Native AOT analysis includes all of the app's code and any libraries the app depends on.
Amaran
The $(PublishAot)
build property shouldn't be conditioned by build configuration. This is because trimming features switches are enabled or disabled based on the value of the $(PublishAot)
build property, and the same features should be enabled or disabled in all build configurations so that your code behaves identically. For more information about trimming feature switches, see Trimming feature switches.
The only way to verify that a Native AOT app works correctly is to publish it using dotnet publish
and verify that there are no trimming or AOT warnings produced by your code and its dependencies. In particular, dotnet build -t:Publish
isn't equivalent to dotnet publish
.
Use the following dotnet publish
command to publish your app on iOS and Mac Catalyst using Native AOT deployment:
# iOS
dotnet publish -f net9.0-ios -r ios-arm64
# Mac Catalyst
dotnet publish -f net9.0-maccatalyst -r maccatalyst-arm64
dotnet publish -f net9.0-maccatalyst -r maccatalyst-x64
# Universal Mac Catalyst apps
# (when <RuntimeIdentifiers>maccatalyst-x64;maccatalyst-arm64</RuntimeIdentifiers> is set in the project file)
dotnet publish -f net9.0-maccatalyst
Petua
Publish apps frequently to discover trimming or AOT issues early in the development lifecycle.
Native AOT will introduce limitations on usage of certain aspects of the .NET runtime, and should only be used in scenarios where app size and performance are important. It'll require you to adapt your apps to Native AOT requirements, which means ensuring that they are fully trimming and AOT compatible, and this can require a lot of work. In addition to the .NET limitations of Native AOT deployment, Native AOT deployment for .NET MAUI has additional limitations.
Third-party libraries your apps depend on might not be AOT compatible. The only way to ensure that a library is trimming and AOT compatible is to publish your app using Native AOT deployment and the dotnet publish
command, and see if the Native AOT compiler produces any warnings for the library. For information about making your own libraries AOT compatible, see How to make libraries compatible with native AOT.
Native AOT deployment limits the use of reflection in your code and its dependencies, and it can become necessary to use annotations to help the Native AOT compiler understand reflection patterns. When the compiler encounters a reflection pattern it can't statically analyze, and hence can't build the app, it produces trim warnings. Native AOT also prevents you from using dynamic code in your app. For example, compiling System.Linq.Expressions won't work as expected, and it isn't possible to load and execute assemblies at runtime. When the compiler encounters a dynamic pattern it can't ahead-of-time compile, it will produce an AOT warning.
In .NET MAUI app this means that:
DynamicallyAccessedMembers
attribute or the DynamicDependency
attribute this is very error prone and isn't recommended.SearchHandler.DisplayMemberName
property might not work. Instead, you should provide an ItemTemplate to define the appearance of SearchHandler results. For more information, see Define search results item appearance.OnPlatform
XAML markup extension isn't possible. Instead, you should use the OnPlatform<T> class. For more information, see Customize UI appearance based on the platform.OnIdiom
XAML markup extension isn't possible. Instead, you should use the OnIdiom<T> class. For more information, see Customize UI appearance based on the device idiom.Penting
The Mono interpreter isn't compatible with Native AOT deployment, and therefore the $(UseInterpreter)
and $(MtouchInterpreter)
MSBuild properties have no effect when using Native AOT. For more information about the Mono interpreter, see Mono interpreter on iOS and Mac Catalyst.
For more information about trim warnings, see Introduction to trim warnings. For more information about AOT warnings, see Introduction to AOT warnings.
Use the following checklist to help you adapt your app to Native AOT deployment requirements:
[XamlCompilation(XamlCompilationOptions.Skip)]
usage.<?xaml-comp compile="false" ?>
usage.x:DataType
.OnPlatform
XAML markup extension usage with an implementation that uses the OnPlatform<T> class. For more information, see Customize UI appearance based on the platform.OnIdiom
XAML markup extension usage with an implementation that uses the OnIdiom<T> class. For more information, see Customize UI appearance based on the device idiom.[QueryProperty(...)]
usage with an implementation of the IQueryAttributable
interface. For more information, see Process navigation data using a single method.SearchHandler.DisplayMemberName
usage with an ItemTemplate. For more information, see Define search results item appearance.A
to type B
, either the ConvertTo
method on a type converter associated with A
will be used or the ConvertFrom
method on a type converter associated with B
will be used.Native AOT and Mono share a subset of diagnostics and instrumentation capabilities. Due to Mono's range of diagnostic tools, it can be beneficial to diagnose and debug issues within Mono instead of Native AOT. Apps that are trim and AOT-compatible shouldn't have behavioral differences, so investigations often apply to both runtimes.
The following table shows the diagnostics support with Native AOT on iOS and Mac Catalyst:
Feature | Fully supported | Partially supported | Not supported |
---|---|---|---|
Observability and telemetry | Partially supported | ||
Development-time diagnostics | Fully supported | ||
Native debugging | Partially supported | ||
CPU Profiling | Partially supported | ||
Heap analysis | Not supported |
The following sections provide additional information about this diagnostics support.
Tracing of .NET MAUI applications on mobile platforms is enabled through dotnet-dsrouter which connects diagnostic tooling with .NET applications running on iOS and Mac Catalyst, over TCP/IP. However, Native AOT is currently not compatible with this scenario as it doesn't support EventPipe/DiagnosticServer components built with the TCP/IP stack. Observability is still achievable explicitly in the code.
.NET CLI tooling provides separate commands for build
and publish
. dotnet build
(or Start Debugging (F5)
in Visual Studio Code), uses Mono by default when building or launching .NET MAUI iOS or Mac Catalyst applications. Only dotnet publish
will create a Native AOT application, if this deployment model is enabled in the project file.
Not all diagnostic tools will work seamlessly with published Native AOT applications. However, all applications that are trim and AOT-compatible (that is, those that don't produce any trim and AOT warnings at build time) shouldn't have behavioral differences between Mono and Native AOT. Therefore, all .NET development-time diagnostic tools, such as Hot Reload, are still available for developers during the mobile application development cycle.
Petua
You should develop, debug, and test your application as usual and publish your final app with Native AOT as one of the last steps.
When you run your .NET MAUI iOS or Mac Catalyst application during development it runs on Mono by default. However, if Native AOT deployment is enabled in the project file, the behavior is expected to be the same between Mono and Native AOT when the application isn't producing any trim and AOT warnings at build time. Provided that your application fulfils this requirement, you can use the standard Visual Studio Code managed debugging engine for development and testing,
After publishing, Native AOT applications are true native binaries and so the managed debugger won't work on them. However, the Native AOT compiler generates fully native executable files that you can debug with lldb
. Debugging a Mac Catalyst app with lldb
is straight forward, as it is executed on the same system. However, debugging NativeAOT iOS applications requires additional effort.
.NET MAUI iOS applications that are compatible with Native AOT and which are properly configured and published with this deployment model, can be debugged as follows:
Publish your app with Native AOT targeting ios-arm64
and note the following information:
<app-name>
).<bundle-identifier>
).<path-to-ipa>
).Obtain your physical device ID (referenced below as <device-identifier>
):
xcrun devicectl list devices
Install the app on your physical device:
xcrun devicectl device install app --device <device-identifier> <path-to-ipa>
Launch the app on your physical device:
xcrun devicectl device process launch --device <device-identifier> --start-stopped <bundle-identifier>
Open lldb
and connect to your physical device:
(lldb) device select <device-identifier>
(lldb) device process attach -n <app-name>
After successfully completing these steps, you'll be able to start debugging your Native AOT .NET MAUI iOS application with lldb
.
By default, debug symbols are stripped from the application's binary file into a .dSYM file. This file is used by debuggers and post mortem analysis tools to show information about local variables, source line numbers, and to recreate stack traces of crash dumps. Therefore, it's essential to preserve the symbol file before submitting your application to the App Store.
Xcode Instruments can be used to collect CPU samples of a Native AOT application.
Heap analysis isn't currently supported with Native AOT.
.NET MAUI maklum balas
.NET MAUI ialah projek sumber terbuka. Pilih pautan untuk memberikan maklum balas:
Latihan
Laluan pembelajaran
Build mobile and desktop apps with .NET MAUI - Training
In this learning path, use C# and Visual Studio with .NET MAUI to create an app that runs across iOS, Android, and Windows.
Dokumentasi
Trim a .NET MAUI app - .NET MAUI
Learn about the .NET trimmer, which eliminates unused code from a .NET MAUI app to reduce its size.
Mono interpreter on iOS and Mac Catalyst - .NET MAUI
Learn how to enable the Mono interpreter, which lets you use dynamic code generation in your .NET MAUI iOS and ARM64-based Mac Catalyst release builds.
Learn how to consume .NET MAUI controls inside .NET for iOS, .NET for Android, and WinUI native apps.