Native AOT-Bereitstellung unter iOS und Mac Catalyst
Die native AOT-Bereitstellung erzeugt eine .NET Multi-Platform App UI (.NET MAUI)-App unter iOS und Mac Catalyst, die vorab (AOT) in systemeigenem Code kompiliert wurde. Native AOT führt statische Programmanalyse durch, vollständige Kürzung Ihrer App, die aggressiv beim Entfernen von Code ist, auf den nicht statisch verwiesen wird, und die Generierung von Vorabcode.
Durch das Veröffentlichen und Bereitstellen einer nativen AOT-App ergeben sich die folgenden Vorteile:
- Reduzierte App-Paketgröße.
- Schnellere Startzeit.
- Schnellere Buildzeit.
Native AOT führt Einschränkungen bei der Verwendung bestimmter Aspekte der .NET-Runtime ein und sollte nur in Szenarien verwendet werden, in denen App-Größe und Leistung wichtig sind. Sie müssen Ihre Apps an native AOT-Anforderungen anpassen, was bedeutet, dass sie vollständig gekürzt und AOT kompatibel sind. Weitere Informationen zu nativen AOT-Einschränkungen finden Sie unter Native AOT-Einschränkungen.
Wenn die native AOT-Bereitstellung aktiviert ist, analysiert das Buildsystem Ihren Code und alle abhängigkeiten, um zu überprüfen, ob sie für die vollständige Kürzung und AOT-Kompilierung geeignet ist. Wenn Inkompatibilitäten erkannt werden, werden Kürzen und AOT-Warnungen erzeugt. Eine einzelne Kürzungs- oder AOT-Warnung bedeutet, dass die App nicht mit der nativen AOT-Bereitstellung kompatibel ist und dass sie möglicherweise nicht ordnungsgemäß funktioniert. Daher sollten Sie beim Erstellen einer App für die native AOT-Bereitstellung alle Kürzungen und AOT-Warnungen überprüfen und korrigieren. Wenn dies nicht möglich ist, kann dies zur Laufzeit zu Ausnahmen führen, da der erforderliche Code entfernt worden sein könnte. Wenn Sie die Warnungen unterdrücken, muss die bereitgestellte AOT-App gründlich getestet werden, um sicherzustellen, dass sich die Funktionalität nicht von der ungetrimmten App geändert hat. Weitere Informationen finden Sie in der Einführung zum Kürzen von Warnungen und einführung in AOT-Warnungen.
Hinweis
Es kann Fälle geben, in denen das Beheben von Kürzungen und AOT-Warnungen nicht möglich ist, z. B. wenn sie für Drittanbieterbibliotheken auftreten. In solchen Fällen müssen Drittanbieterbibliotheken aktualisiert werden, um vollständig kompatibel zu werden.
Vorteile der systemeigenen AOT-Leistung
Veröffentlichung und Bereitstellung einer nativen AOT-App erzeugt eine App, die in der Regel bis zu 2,5x kleiner ist, und eine App, die in der Regel bis zu 2x schneller gestartet wird. Die genauen Leistungsvorteile sind jedoch von mehreren Faktoren abhängig, einschließlich der verwendeten Plattform, des Geräts, auf dem die App ausgeführt wird, und der App selbst.
Wichtig
Die folgenden Diagramme zeigen typische Leistungsvorteile der nativen AOT-Bereitstellung für eine dotnet new maui
App unter iOS und Mac Catalyst. Die genauen Daten sind jedoch hardwareabhängig und können sich in zukünftigen Versionen ändern.
Das folgende Diagramm zeigt die Größe des App-Pakets für eine dotnet new maui
App unter iOS und Mac Catalyst in verschiedenen Bereitstellungsmodellen:
Das obige Diagramm zeigt, dass native AOT im Vergleich zum Standardbereitstellungsmodell mehr als 2x kleinere Apps für iOS und Mac Catalyst erzeugt.
Das folgende Diagramm zeigt die durchschnittliche Startzeit auf bestimmter Hardware für eine dotnet new maui
App unter iOS und Mac Catalyst auf Mono und native AOT-Bereitstellung:
Das obige Diagramm zeigt, dass Native AOT in der Regel bis zu 2x schnellere Startzeiten auf iOS-Geräten und 1,2x schnellere Startzeit auf Mac Catalyst im Vergleich zur Mono-Bereitstellung aufweist.
Das folgende Diagramm zeigt die durchschnittliche Buildzeit auf bestimmter Hardware für eine dotnet new maui
App unter iOS und Mac Catalyst in verschiedenen Bereitstellungsmodellen:
Das obige Diagramm zeigt, dass in der Regel native AOT im Vergleich zum Standardbereitstellungsmodell bis zu 2,8x schnellere Buildzeiten auf iOS-Geräten aufweist. Für Mac Catalyst sind Buildzeiten für arm64 single RID-Apps vergleichbar, sind aber im Vergleich zur Mono-Bereitstellung etwas langsamer für universelle Apps.
Wichtig
In vielen Szenarien erzeugt Native AOT kleinere und schnellere Apps. In einigen Szenarien erzeugt Native AOT jedoch möglicherweise keine kleineren und schnelleren Apps. Daher ist es wichtig, Ihre App zu testen und zu profilieren, um das Ergebnis der Aktivierung der nativen AOT-Bereitstellung zu ermitteln.
Veröffentlichen mit nativem AOT
Das systemeigene AOT-Bereitstellungsmodell ist mit der $(PublishAot)
Buildeigenschaft und dem dotnet publish
Befehl aktiviert. Das folgende Beispiel zeigt, wie Sie eine Projektdatei ändern, um die native AOT-Bereitstellung unter iOS und Mac Catalyst zu aktivieren:
<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>
Das Festlegen der $(IsAotCompatible)
Buildeigenschaft auf true
, für alle Plattformen, ermöglicht das Kürzen und AOT-Analysatoren. Diese Analysegeräte helfen Ihnen, Code zu identifizieren, der nicht mit dem Kürzen oder AOT kompatibel ist.
Die bedingte Einstellung $(PublishAot)
für true
iOS und Mac Catalyst ermöglicht während des Builds und der nativen AOT-Kompilierung während der Veröffentlichung dynamische Codeverwendungsanalysen. Die systemeigene AOT-Analyse umfasst den gesamten App-Code und alle Bibliotheken, von der die App abhängig ist.
Warnung
Die $(PublishAot)
Buildeigenschaft sollte nicht durch die Buildkonfiguration bedingt werden. Dies liegt daran, dass Kürzungsfeature-Switches basierend auf dem Wert der $(PublishAot)
Buildeigenschaft aktiviert oder deaktiviert sind und dieselben Features in allen Buildkonfigurationen aktiviert oder deaktiviert werden sollten, damit sich Ihr Code identisch verhält. Weitere Informationen zum Kürzen von Featureoptionen finden Sie unter "Trimming Feature Switches".
Die einzige Möglichkeit, zu überprüfen, ob eine native AOT-App ordnungsgemäß funktioniert, besteht darin, sie mithilfe dotnet publish
von Veröffentlichungen zu veröffentlichen und zu überprüfen, ob keine Kürzungs- oder AOT-Warnungen vorhanden sind, die von Ihrem Code und den zugehörigen Abhängigkeiten erzeugt werden. Insbesondere dotnet build -t:Publish
entspricht dies nicht dem dotnet publish
.
Verwenden Sie den folgenden dotnet publish
Befehl, um Ihre App unter iOS und Mac Catalyst mithilfe der nativen AOT-Bereitstellung zu veröffentlichen:
# 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
Tipp
Veröffentlichen Sie Apps häufig, um Kürzen oder AOT-Probleme frühzeitig im Entwicklungslebenszyklus zu ermitteln.
Systemeigene AOT-Einschränkungen
Native AOT führt Einschränkungen bei der Verwendung bestimmter Aspekte der .NET-Runtime ein und sollte nur in Szenarien verwendet werden, in denen App-Größe und Leistung wichtig sind. Sie müssen Ihre Apps an systemeigene AOT-Anforderungen anpassen, was bedeutet, dass sie vollständig gekürzt und AOT kompatibel sind, und dies kann viel Arbeit erfordern. Zusätzlich zu den .NET-Einschränkungen der nativen AOT-Bereitstellung hat die native AOT-Bereitstellung für .NET MAUI zusätzliche Einschränkungen.
Drittanbieterbibliotheken, von denen Ihre Apps abhängen, sind möglicherweise nicht mit AOT kompatibel. Die einzige Möglichkeit, sicherzustellen, dass eine Bibliothek gekürzt und AOT kompatibel ist, besteht darin, Ihre App mithilfe der nativen AOT-Bereitstellung und des dotnet publish
Befehls zu veröffentlichen, und überprüfen Sie, ob der native AOT-Compiler Warnungen für die Bibliothek erzeugt. Informationen zum Erstellen eigener Bibliotheken mit AOT-kompatiblen Bibliotheken finden Sie unter How to make libraries compatible with native AOT.For information about making your own libraries AOT compatible, see How to make libraries compatible with native AOT.
Spiegelung und dynamischer Code
Die native AOT-Bereitstellung beschränkt die Verwendung der Spiegelung in Ihrem Code und deren Abhängigkeiten, und es kann erforderlich werden, Anmerkungen zu verwenden, um dem nativen AOT-Compiler das Verständnis von Spiegelungsmustern zu erleichtern. Wenn der Compiler auf ein Spiegelungsmuster stößt, das nicht statisch analysiert werden kann und daher die App nicht erstellen kann, werden Warnungen erzeugt. Native AOT verhindert auch, dass Sie dynamischen Code in Ihrer App verwenden. Die Kompilierung System.Linq.Expressions funktioniert beispielsweise nicht wie erwartet, und es ist nicht möglich, Assemblys zur Laufzeit zu laden und auszuführen. Wenn der Compiler auf ein dynamisches Muster trifft, kann es nicht vorab kompiliert werden, wird eine AOT-Warnung erzeugt.
In der .NET MAUI-App bedeutet dies Folgendes:
- Alle XAML-Code müssen vorab kompiliert werden. Stellen Sie daher sicher, dass Sie die XAML-Kompilierung nicht deaktiviert haben und dass alle Bindungen kompiliert werden. Weitere Informationen finden Sie unter XAML-Kompilierung und kompilierte Bindungen.
- Alle Bindungsausdrücke müssen kompilierte Bindungen anstelle eines Bindungspfads verwenden, der auf eine Zeichenfolge festgelegt ist. Für weitere Informationen siehe Kompilierte Bindungen.
- Implizite Konvertierungsoperatoren werden möglicherweise beim Zuweisen eines Werts eines inkompatiblen Typs zu einer Eigenschaft in XAML nicht aufgerufen, oder wenn zwei Eigenschaften unterschiedlicher Typen eine Datenbindung verwenden. Stattdessen sollten Sie einen TypeConverter für Ihren Typ definieren und ihn mithilfe des TypeConverterAttributeTyps anfügen. Weitere Informationen finden Sie unter Define a TypeConverter to replace an implicit conversion operator.
- Es ist nicht möglich, XAML zur Laufzeit mit der LoadFromXaml Methode zu analysieren. Dies kann zwar durch Kommentieren aller Typen, die zur Laufzeit mit dem
DynamicallyAccessedMembers
Attribut geladen werden können, oder dasDynamicDependency
Attribut ist sehr fehleranfällig und wird nicht empfohlen. - Das Empfangen von Navigationsdaten mithilfe der QueryPropertyAttribute Daten funktioniert nicht. Stattdessen sollten Sie die IQueryAttributable Schnittstelle für Typen implementieren, die Abfrageparameter akzeptieren müssen. Weitere Informationen finden Sie unter Verarbeiten von Navigationsdaten mit einer einzelnen Methode.
- Die
SearchHandler.DisplayMemberName
Eigenschaft funktioniert möglicherweise nicht. Stattdessen sollten Sie ein ItemTemplate bereitstellen, um das Erscheinungsbild der SearchHandler-Ergebnisse zu definieren. Weitere Informationen finden Sie unter Definieren der Darstellung von Suchergebnissen.
Wichtig
Der Mono-Interpreter ist nicht mit der nativen AOT-Bereitstellung kompatibel, und daher haben die $(UseInterpreter)
$(MtouchInterpreter)
MSBuild-Eigenschaften keine Auswirkungen, wenn Native AOT verwendet wird. Weitere Informationen zum Mono-Dolmetscher finden Sie unter Mono-Interpreter unter iOS und Mac Catalyst.
Weitere Informationen zum Kürzen von Warnungen finden Sie in der Einführung in das Kürzen von Warnungen. Weitere Informationen zu AOT-Warnungen finden Sie in der Einführung in AOT-Warnungen.
Anpassen einer App an die native AOT-Bereitstellung
Verwenden Sie die folgende Checkliste, um Ihre App an systemeigene AOT-Bereitstellungsanforderungen anzupassen:
- Stellen Sie sicher, dass alle XAML-Dateien kompiliert werden:
- Entfernen Sie alle
[XamlCompilation(XamlCompilationOptions.Skip)]
Verwendungen. - Entfernen Sie alle
<?xaml-comp compile="false" ?>
Verwendungen.
- Entfernen Sie alle
- Entfernen Sie alle Aufrufe der LoadFromXaml Methode.
- Stellen Sie sicher, dass alle Datenbindungen kompiliert werden. Für weitere Informationen siehe Kompilierte Bindungen.
- Stellen Sie sicher, dass alle XAML-Datenbindungen mit
x:DataType
Anmerkungen versehen sind. - Stellen Sie sicher, dass alle Codedatenbindungen alle zeichenfolgenbasierten Bindungen durch Lambda-basierte Bindungen ersetzen.
- Stellen Sie sicher, dass alle XAML-Datenbindungen mit
- Ersetzen Sie alle
[QueryProperty(...)]
Verwendung durch eine Implementierung derIQueryAttributable
Schnittstelle. Weitere Informationen finden Sie unter Verarbeiten von Navigationsdaten mit einer einzelnen Methode. - Ersetzen Sie alle
SearchHandler.DisplayMemberName
Verwendungen durch eine ItemTemplate. Weitere Informationen finden Sie unter Definieren der Darstellung von Suchergebnissen. - Ersetzen Sie alle impliziten Konvertierungsoperatoren für Typen, die in XAML verwendet werden, durch eine TypeConverter, und fügen Sie sie mit der TypeConverterAttribute Weitere Informationen finden Sie unter Define a TypeConverter to replace an implicit conversion operator.
- Beim Konvertieren vom Typ
A
in den TypB
wird entweder dieConvertTo
Methode für einen Typkonverter verwendet, der zugeordnetA
ist, oder die Methode für einen Typkonverter verwendet, derConvertFrom
B
einem Typkonverter zugeordnet ist. - Wenn sowohl Quell- als auch Zieltypen über einen zugeordneten Typkonverter verfügen, kann eine dieser Typen verwendet werden.
- Beim Konvertieren vom Typ
- Kompilieren Sie alle regulären Ausdrücke mithilfe von Quellgeneratoren. Weitere Informationen finden Sie unter Quellgeneratoren für reguläre .NET-Ausdrücke.
- Stellen Sie sicher, dass die JSON-Serialisierung und Deserialisierung einen generierten Quellkontext verwendet. Weitere Informationen finden Sie unter Minimal-APIs und JSON-Nutzlasten.
- Überprüfen und korrigieren Sie alle Kürzungs- oder AOT-Warnungen. Weitere Informationen finden Sie in der Einführung zum Kürzen von Warnungen und einführung in AOT-Warnungen.
- Testen Sie Ihre App gründlich.
Native AOT-Diagnoseunterstützung für iOS und Mac Catalyst
Native AOT und Mono teilen eine Teilmenge der Diagnose- und Instrumentierungsfunktionen. Aufgrund der Reihe von Diagnosetools von Mono kann es vorteilhaft sein, Probleme innerhalb von Mono anstelle von Native AOT zu diagnostizieren und zu debuggen. Apps, die kürzen und AOT-kompatibel sind, sollten keine Verhaltensunterschiede aufweisen, daher gelten Untersuchungen häufig für beide Laufzeiten.
Die folgende Tabelle zeigt die Diagnoseunterstützung mit Native AOT unter iOS und Mac Catalyst:
Funktion | Vollständig unterstützt | Teilweise unterstützt | Nicht unterstützt |
---|---|---|---|
Einblick und Telemetrie | Teilweise unterstützt | ||
Entwicklungszeitdiagnose | Vollständig unterstützt | ||
Systemeigenes Debuggen | Teilweise unterstützt | ||
CPU-Profilerstellung | Teilweise unterstützt | ||
Heapanalyse | Nicht unterstützt |
Die folgenden Abschnitte enthalten zusätzliche Informationen zu dieser Diagnoseunterstützung.
Einblick und Telemetrie
Die Ablaufverfolgung von .NET MAUI-Anwendungen auf mobilen Plattformen wird über dotnet-dsrouter aktiviert, der Diagnosetools mit .NET-Anwendungen verbindet, die unter iOS und Mac Catalyst ausgeführt werden, über TCP/IP. Native AOT ist derzeit jedoch nicht mit diesem Szenario kompatibel, da es keine EventPipe/DiagnosticServer-Komponenten unterstützt, die mit dem TCP/IP-Stapel erstellt wurden. Observability ist im Code immer noch explizit erreichbar.
Entwicklungszeitdiagnose
.NET CLI-Tools bieten separate Befehle für build
und publish
. dotnet build
(oder Start Debugging (F5)
in Visual Studio Code) verwendet Mono standardmäßig beim Erstellen oder Starten von .NET MAUI iOS- oder Mac Catalyst-Anwendungen. Erstellt nur dotnet publish
eine native AOT-Anwendung, wenn dieses Bereitstellungsmodell in der Projektdatei aktiviert ist.
Nicht alle Diagnosetools funktionieren nahtlos mit veröffentlichten nativen AOT-Anwendungen. Alle Anwendungen, die kürzen und AOT-kompatibel sind (d. h. diejenigen, die zur Erstellungszeit keine Kürzungen erzeugen, und AOT-Warnungen sollten keine Verhaltensunterschiede zwischen Mono und Native AOT aufweisen. Daher sind alle .NET-Entwicklungszeit-Diagnosetools, z. B. Hot Reload, während des Entwicklungszyklus mobiler Anwendungen weiterhin für Entwickler verfügbar.
Tipp
Sie sollten Ihre Anwendung wie gewohnt entwickeln, debuggen und testen und ihre endgültige App mit Native AOT als einer der letzten Schritte veröffentlichen.
Systemeigenes Debuggen
Wenn Sie Ihre .NET MAUI iOS- oder Mac Catalyst-Anwendung während der Entwicklung ausführen, wird sie standardmäßig auf Mono ausgeführt. Wenn die native AOT-Bereitstellung jedoch in der Projektdatei aktiviert ist, wird davon ausgegangen, dass das Verhalten zwischen Mono und Native AOT identisch ist, wenn die Anwendung zur Erstellungszeit keine Kürzungs- und AOT-Warnungen erzeugt. Sofern Ihre Anwendung diese Anforderung erfüllt, können Sie das standardmäßige verwaltete Debugmodul von Visual Studio Code für Die Entwicklung und Tests verwenden,
Nach der Veröffentlichung sind native AOT-Anwendungen echte systemeigene Binärdateien, sodass der verwaltete Debugger nicht mehr funktioniert. Der native AOT-Compiler generiert jedoch vollständig systemeigene ausführbare Dateien, mit lldb
denen Sie debuggen können. Das Debuggen einer Mac Catalyst-App ist lldb
gerade vorwärts, da sie auf demselben System ausgeführt wird. Das Debuggen von NativeAOT iOS-Anwendungen erfordert jedoch zusätzlichen Aufwand.
Debuggen von .NET MAUI iOS-Anwendungen mit nativem AOT
.NET MAUI iOS-Anwendungen, die mit nativem AOT kompatibel sind und mit diesem Bereitstellungsmodell ordnungsgemäß konfiguriert und veröffentlicht werden, können wie folgt gedebuggt werden:
Veröffentlichen Sie Ihre App mit nativer AOT-Zielbestimmung
ios-arm64
, und notieren Sie sich die folgenden Informationen:- Anwendungsname (unten referenziert als
<app-name>
). - Bündelbezeichner (referenziert unten als
<bundle-identifier>
). - Pfad zur ARCHIV-IPA-Datei der veröffentlichten Anwendung (siehe unten).
<path-to-ipa>
- Anwendungsname (unten referenziert als
Rufen Sie Ihre physische Geräte-ID ab (siehe unten
<device-identifier>
):xcrun devicectl list devices
Installieren Sie die App auf Ihrem physischen Gerät:
xcrun devicectl device install app --device <device-identifier> <path-to-ipa>
Starten Sie die App auf Ihrem physischen Gerät:
xcrun devicectl device process launch --device <device-identifier> --start-stopped <bundle-identifier>
Öffnen
lldb
und Herstellen einer Verbindung mit Ihrem physischen Gerät:(lldb) device select <device-identifier> (lldb) device process attach -n <app-name>
Nachdem Sie diese Schritte erfolgreich abgeschlossen haben, können Sie mit dem Debuggen Ihrer nativen AOT .NET MAUI iOS-Anwendung beginnen.lldb
Bedeutung der Symboldatei
Standardmäßig werden Debugsymbole aus der Binärdatei der Anwendung in eine DSYM-Datei entfernt. Diese Datei wird von Debuggern und Tools nach der Mortemanalyse verwendet, um Informationen zu lokalen Variablen, Quellzeilennummern anzuzeigen und Stapelüberwachungen von Absturzabbildern neu zu erstellen. Daher ist es wichtig, die Symboldatei beizubehalten, bevor Sie Ihre Anwendung an den App Store übermitteln.
CPU-Profilerstellung
Xcode-Instrumente können verwendet werden, um CPU-Proben einer nativen AOT-Anwendung zu sammeln.
Heapanalyse
Heap-Analyse wird derzeit nicht mit Native AOT unterstützt.