Freigeben über


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:

Diagramm, das die Größe des App-Pakets in verschiedenen Bereitstellungsmodellen anzeigt.

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:

Diagramm mit durchschnittlicher Startzeit der App auf Mono und nativem AOT.

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:

Diagramm mit durchschnittlicher App-Buildzeit für Mono und native AOT.

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 trueiOS 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 das DynamicDependency 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 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:DataTypeAnmerkungen versehen sind.
    • Stellen Sie sicher, dass alle Codedatenbindungen alle zeichenfolgenbasierten Bindungen durch Lambda-basierte Bindungen ersetzen.
  • Ersetzen Sie alle [QueryProperty(...)] Verwendung durch eine Implementierung der IQueryAttributable 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 Typ Bwird entweder die ConvertTo Methode für einen Typkonverter verwendet, der zugeordnet A ist, oder die Methode für einen Typkonverter verwendet, der ConvertFrom B einem Typkonverter zugeordnet ist.
    • Wenn sowohl Quell- als auch Zieltypen über einen zugeordneten Typkonverter verfügen, kann eine dieser Typen verwendet werden.
  • 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 lldbdenen 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:

  1. 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>
  2. Rufen Sie Ihre physische Geräte-ID ab (siehe unten <device-identifier>):

    xcrun devicectl list devices
    
  3. Installieren Sie die App auf Ihrem physischen Gerät:

    xcrun devicectl device install app --device <device-identifier> <path-to-ipa>
    
  4. Starten Sie die App auf Ihrem physischen Gerät:

    xcrun devicectl device process launch --device <device-identifier> --start-stopped <bundle-identifier>
    
  5. Ö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.

Siehe auch