Déploiement AOT natif sur iOS et Mac Catalyst
Le déploiement AOT natif produit une application d’interface utilisateur d’application multiplateforme .NET (.NET MAUI) sur iOS et Mac Catalyst compilée à l’avance (AOT) en code natif. Native AOT effectue une analyse de programme statique, le découpage complet de votre application, qui est agressif dans la suppression du code qui n’est pas référencé statiquement et la génération de code à l’avance.
La publication et le déploiement d’une application AOT native produisent les avantages suivants :
- Taille réduite du package d’application.
- Temps de démarrage plus rapide.
- Temps de génération plus rapide.
L’AOT natif introduit des limitations sur l’utilisation de certains aspects du runtime .NET et ne doit être utilisée que dans les scénarios où la taille et les performances de l’application sont importantes. Il vous faudra adapter vos applications aux exigences AOT natives, ce qui signifie qu’elles sont entièrement rognantes et compatibles avec AOT. Pour plus d’informations sur les limitations AOT natives, consultez limitations DOT natives.
Lorsque le déploiement AOT natif est activé, le système de génération analyse votre code et toutes ses dépendances, pour vérifier s’il convient pour le découpage complet et la compilation AOT. Si des incompatibilités sont détectées, le découpage et les avertissements AOT sont générés. Un avertissement de découpage unique ou AOT signifie que l’application n’est pas compatible avec le déploiement AOT natif et qu’elle peut ne pas fonctionner correctement. Par conséquent, lors de la création d’une application pour le déploiement AOT natif, vous devez passer en revue et corriger tous les avertissements de découpage et AOT. L’échec de cette opération peut entraîner des exceptions au moment de l’exécution, car le code nécessaire a pu être supprimé. Si vous supprimez les avertissements que l’application déployée AOT doit être soigneusement testée pour vérifier que la fonctionnalité n’a pas changé de l’application nontrimmée. Pour plus d’informations, consultez Présentation des avertissements de suppression et Introduction aux avertissements AOT.
Remarque
Il peut y avoir des cas où la correction de la suppression et des avertissements AOT n’est pas possible, par exemple lorsqu’elles se produisent pour les bibliothèques tierces. Dans ce cas, les bibliothèques tierces doivent être mises à jour pour devenir entièrement compatibles.
Avantages en matière de performances AOT natifs
La publication et le déploiement d’une application AOT native produisent une application qui est généralement jusqu’à 2,5x plus petite, et une application qui démarre généralement jusqu’à 2 fois plus rapidement. Toutefois, les avantages exacts en matière de performances dépendent de plusieurs facteurs qui incluent la plateforme utilisée, l’appareil sur lequel l’application est en cours d’exécution et l’application elle-même.
Important
Les graphiques suivants présentent des avantages de performances typiques du déploiement AOT natif pour une dotnet new maui
application sur iOS et Mac Catalyst. Toutefois, les données exactes dépendent du matériel et peuvent changer dans les versions ultérieures.
Le graphique suivant montre la taille du package d’application pour une dotnet new maui
application sur iOS et Mac Catalyst sur différents modèles de déploiement :
Le graphique précédent montre que, généralement, Native AOT produit plus de 2x applications plus petites pour iOS et Mac Catalyst par rapport au modèle de déploiement par défaut.
Le graphique suivant montre le temps de démarrage moyen, sur un matériel spécifique, pour une dotnet new maui
application sur iOS et Mac Catalyst sur un déploiement Mono et AOT natif :
Le graphique précédent montre que L’AOT natif a généralement jusqu’à 2 fois plus de temps de démarrage plus rapides sur les appareils iOS et une durée de démarrage 1,2 fois plus rapide sur Mac Catalyst, par rapport au déploiement Mono.
Le graphique suivant montre le temps de génération moyen, sur un matériel spécifique, pour une dotnet new maui
application sur iOS et Mac Catalyst sur différents modèles de déploiement :
Le graphique précédent montre que l’AOT natif a jusqu’à 2,8 fois de build plus rapides sur les appareils iOS par rapport au modèle de déploiement par défaut. Pour Mac Catalyst, les temps de génération sont comparables pour les applications RID uniques arm64, mais sont légèrement plus lents pour les applications universelles par rapport au déploiement Mono.
Important
Dans de nombreux scénarios, L’AOT natif génère des applications plus petites et plus rapides. Toutefois, dans certains scénarios, L’AOT natif peut ne pas produire d’applications plus petites et plus rapides. Par conséquent, il est important de tester et de profiler votre application pour déterminer le résultat de l’activation du déploiement AOT natif.
Publier à l’aide d’AOT natif
Le modèle de déploiement AOT natif est activé avec la $(PublishAot)
propriété de build et la dotnet publish
commande. L’exemple suivant montre comment modifier un fichier projet pour activer le déploiement AOT natif sur iOS et 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>
La définition de la $(IsAotCompatible)
propriété true
de build sur , pour toutes les plateformes, active le découpage et les analyseurs AOT. Ces analyseurs vous aident à identifier le code qui n’est pas compatible avec le découpage ou LOT.
La définition $(PublishAot)
true
conditionnelle sur , pour iOS et Mac Catalyst, active l’analyse dynamique de l’utilisation du code lors de la compilation de build et d’AOT native lors de la publication. L’analyse AOT native inclut tout le code de l’application et toutes les bibliothèques dont dépend l’application.
Avertissement
La $(PublishAot)
propriété de build ne doit pas être conditionnée par la configuration de build. Cela est dû au fait que les commutateurs de fonctionnalités de découpage sont activés ou désactivés en fonction de la valeur de la $(PublishAot)
propriété de build, et que les mêmes fonctionnalités doivent être activées ou désactivées dans toutes les configurations de build afin que votre code se comporte de manière identique. Pour plus d’informations sur le découpage des commutateurs de fonctionnalités, consultez Découpage des commutateurs de fonctionnalités.
La seule façon de vérifier qu’une application AOT native fonctionne correctement consiste à la publier à l’aide dotnet publish
et à vérifier qu’il n’y a pas de découpage ou d’avertissements AOT générés par votre code et ses dépendances. En particulier, dotnet build -t:Publish
n’est pas équivalent à dotnet publish
.
Utilisez la commande suivante dotnet publish
pour publier votre application sur iOS et Mac Catalyst à l’aide du déploiement AOT natif :
# 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
Conseil
Publiez fréquemment des applications pour découvrir les problèmes de découpage ou DOT au début du cycle de vie du développement.
Limitations D’AOT natives
L’AOT natif introduit des limitations sur l’utilisation de certains aspects du runtime .NET et ne doit être utilisée que dans les scénarios où la taille et les performances de l’application sont importantes. Il vous faudra adapter vos applications aux exigences AOT natives, ce qui signifie qu’elles sont entièrement rognantes et compatibles avec AOT, et cela peut nécessiter beaucoup de travail. Outre les limitations .NET du déploiement AOT natif, le déploiement AOT natif pour .NET MAUI présente des limitations supplémentaires.
Les bibliothèques tierces dont dépendent vos applications peuvent ne pas être compatibles avec AOT. La seule façon de s’assurer qu’une bibliothèque est rognante et compatible avec AOT consiste à publier votre application à l’aide du déploiement AOT natif et de la dotnet publish
commande, et à voir si le compilateur AOT natif génère des avertissements pour la bibliothèque. Pour plus d’informations sur la compatibilité de vos propres bibliothèques AOT, consultez Comment rendre les bibliothèques compatibles avec AOT natif.
Réflexion et code dynamique
Le déploiement AOT natif limite l’utilisation de la réflexion dans votre code et ses dépendances, et il peut devenir nécessaire d’utiliser des annotations pour aider le compilateur AOT natif à comprendre les modèles de réflexion. Lorsque le compilateur rencontre un modèle de réflexion, il ne peut pas analyser statiquement et ne peut donc pas générer l’application, il génère des avertissements de découpage. L’AOT natif vous empêche également d’utiliser du code dynamique dans votre application. Par exemple, la System.Linq.Expressions compilation ne fonctionnera pas comme prévu, et il n’est pas possible de charger et d’exécuter des assemblys au moment de l’exécution. Lorsque le compilateur rencontre un modèle dynamique qu’il ne peut pas compiler à l’avance, il génère un avertissement AOT.
Dans l’application .NET MAUI, cela signifie que :
- Tous les xamls doivent être compilés à l’avance. Par conséquent, vérifiez que vous n’avez pas désactivé la compilation XAML et que toutes les liaisons sont compilées. Pour plus d’informations, consultez compilation XAML et liaisons compilées.
- Toutes les expressions de liaison doivent utiliser des liaisons compilées, plutôt qu’un chemin d’accès de liaison défini sur une chaîne. Pour plus d’informations, consultez Liaisons compilées.
- Les opérateurs de conversion implicite peuvent ne pas être appelés lors de l’affectation d’une valeur d’un type incompatible à une propriété en XAML, ou lorsque deux propriétés de types différents utilisent une liaison de données. Au lieu de cela, vous devez définir un TypeConverter type pour votre type et l’attacher au type à l’aide du TypeConverterAttribute. Pour plus d’informations, consultez Définir un TypeConverter pour remplacer un opérateur de conversion implicite.
- Il n’est pas possible d’analyser XAML au moment de l’exécution avec la LoadFromXaml méthode. Bien que cela puisse être rendu sécurisé en annotant tous les types qui peuvent être chargés lors de l’exécution avec l’attribut
DynamicallyAccessedMembers
ou l’attributDynamicDependency
, il est très sujette à des erreurs et n’est pas recommandé. - La réception de données de navigation à l’aide du QueryPropertyAttribute fichier ne fonctionnera pas. Au lieu de cela, vous devez implémenter l’interface IQueryAttributable sur les types qui doivent accepter les paramètres de requête. Pour plus d’informations, consultez Traiter les données de navigation à l’aide d’une méthode unique.
- La
SearchHandler.DisplayMemberName
propriété peut ne pas fonctionner. Au lieu de cela, vous devez fournir un ItemTemplate pour définir l’apparence des résultats SearchHandler. Pour plus d’informations, consultez Définir l’apparence de l’élément de résultats de recherche.
Important
L’interpréteur Mono n’est pas compatible avec le déploiement AOT natif. Par conséquent, les propriétés MSBuild et $(MtouchInterpreter)
MSBuild n’ont aucun effet lors de l’utilisation $(UseInterpreter)
d’AOT natif. Pour plus d’informations sur l’interpréteur Mono, consultez l’interpréteur Mono sur iOS et Mac Catalyst.
Pour plus d’informations sur les avertissements de découpage, consultez Présentation des avertissements de suppression. Pour plus d’informations sur les avertissements AOT, consultez Introduction aux avertissements AOT.
Adapter une application au déploiement AOT natif
Utilisez la liste de contrôle suivante pour vous aider à adapter votre application aux exigences de déploiement AOT natives :
- Vérifiez que tous les xamls sont compilés :
- Supprimez toute
[XamlCompilation(XamlCompilationOptions.Skip)]
l’utilisation. - Supprimez toute
<?xaml-comp compile="false" ?>
l’utilisation.
- Supprimez toute
- Supprimez tous les appels à la LoadFromXaml méthode.
- Vérifiez que toutes les liaisons de données sont compilées. Pour plus d’informations, consultez Liaisons compilées.
- Vérifiez que toutes les liaisons de données XAML sont annotées avec
x:DataType
. - Vérifiez que toutes les liaisons de données de code remplacent toutes les liaisons basées sur des chaînes par des liaisons lambda.
- Vérifiez que toutes les liaisons de données XAML sont annotées avec
- Remplacez toute
[QueryProperty(...)]
l’utilisation par une implémentation de l’interfaceIQueryAttributable
. Pour plus d’informations, consultez Traiter les données de navigation à l’aide d’une méthode unique. - Remplacez toute
SearchHandler.DisplayMemberName
l’utilisation par un ItemTemplate. Pour plus d’informations, consultez Définir l’apparence de l’élément de résultats de recherche. - Remplacez tous les opérateurs de conversion implicite pour les types utilisés en XAML par un TypeConverter, et attachez-le à votre type à l’aide du TypeConverterAttributefichier . Pour plus d’informations, consultez Définir un TypeConverter pour remplacer un opérateur de conversion implicite.
- Lors de la conversion d’un type en type
A
B
, laConvertTo
méthode sur un convertisseur de type associéA
sera utilisée ou laConvertFrom
méthode sur un convertisseur de type associéB
sera utilisée. - Lorsque les types source et cible ont un convertisseur de type associé, l’un d’eux peut être utilisé.
- Lors de la conversion d’un type en type
- Compilez toutes les expressions régulières à l’aide de générateurs sources. Pour plus d’informations, consultez Générateurs de sources d’expressions régulières .NET.
- Vérifiez que la sérialisation et la désérialisation JSON utilisent un contexte généré par la source. Pour plus d’informations, consultez Les API minimales et les charges utiles JSON.
- Passez en revue et corrigez les avertissements AOT ou de découpage. Pour plus d’informations, consultez Présentation des avertissements de suppression et Introduction aux avertissements AOT.
- Testez soigneusement votre application.
Prise en charge des diagnostics AOT natifs sur iOS et Mac Catalyst
Native AOT et Mono partagent un sous-ensemble de fonctionnalités de diagnostic et d’instrumentation. En raison de la gamme d’outils de diagnostic de Mono, il peut être utile de diagnostiquer et de déboguer des problèmes au sein de Mono au lieu d’AOT natif. Les applications qui sont tronquées et compatibles avec AOT ne doivent pas avoir de différences comportementales, de sorte que les enquêtes s’appliquent souvent aux deux runtimes.
Le tableau suivant présente la prise en charge des diagnostics avec Native AOT sur iOS et Mac Catalyst :
Fonctionnalité | Entièrement prise en charge | Partiellement prise en charge | Non pris en charge |
---|---|---|---|
Observabilité et télémétrie | Prise en charge partielle | ||
Diagnostics au moment du développement | Prise en charge intégrale | ||
Débogage natif | Prise en charge partielle | ||
Profilage du processeur | Prise en charge partielle | ||
Analyse de tas | Non pris en charge |
Les sections suivantes fournissent des informations supplémentaires sur cette prise en charge des diagnostics.
Observabilité et télémétrie
Le suivi des applications .NET MAUI sur les plateformes mobiles est activé via dotnet-dsrouter qui connecte les outils de diagnostic avec les applications .NET s’exécutant sur iOS et Mac Catalyst, via TCP/IP. Toutefois, L’AOT natif n’est actuellement pas compatible avec ce scénario, car il ne prend pas en charge les composants EventPipe/DiagnosticServer générés avec la pile TCP/IP. L’observabilité est toujours réalisable explicitement dans le code.
Diagnostics au moment du développement
Les outils CLI .NET fournissent des commandes distinctes pour build
et publish
. dotnet build
(ou Start Debugging (F5)
dans Visual Studio Code), utilise Mono par défaut lors de la génération ou du lancement d’applications .NET MAUI iOS ou Mac Catalyst. Crée uniquement dotnet publish
une application AOT native si ce modèle de déploiement est activé dans le fichier projet.
Tous les outils de diagnostic ne fonctionnent pas en toute transparence avec les applications AOT natives publiées. Toutefois, toutes les applications compatibles avec AOT (c’est-à-dire celles qui ne produisent pas d’avertissements de découpage et DOT au moment de la génération) ne doivent pas avoir de différences comportementales entre Mono et AOT natif. Par conséquent, tous les outils de diagnostic au moment du développement .NET, tels que Rechargement à chaud, sont toujours disponibles pour les développeurs pendant le cycle de développement d’applications mobiles.
Conseil
Vous devez développer, déboguer et tester votre application comme d’habitude et publier votre application finale avec Native AOT comme l’une des dernières étapes.
Débogage natif
Lorsque vous exécutez votre application .NET MAUI iOS ou Mac Catalyst pendant le développement, elle s’exécute sur Mono par défaut. Toutefois, si le déploiement AOT natif est activé dans le fichier projet, le comportement est supposé être le même entre Mono et AOT natif lorsque l’application ne produit pas d’avertissements de découpage et DOT au moment de la génération. À condition que votre application réponde à cette exigence, vous pouvez utiliser le moteur de débogage managé Visual Studio Code standard pour le développement et le test,
Après la publication, les applications AOT natives sont des fichiers binaires natifs et le débogueur managé ne fonctionnera donc pas dessus. Toutefois, le compilateur AOT natif génère des fichiers exécutables entièrement natifs que vous pouvez déboguer avec lldb
. Le débogage d’une application Mac Catalyst avec lldb
est simple, car elle est exécutée sur le même système. Toutefois, le débogage d’applications iOS NativeAOT nécessite un effort supplémentaire.
Déboguer des applications iOS .NET MAUI avec AOT natif
Les applications iOS .NET MAUI compatibles avec AOT natif et qui sont correctement configurées et publiées avec ce modèle de déploiement peuvent être déboguées comme suit :
Publiez votre application avec le
ios-arm64
ciblage AOT natif et notez les informations suivantes :- Nom de l’application (référencé ci-dessous en tant que
<app-name>
). - Identificateur de bundle (référencé ci-dessous en tant que
<bundle-identifier>
). - Chemin d’accès au fichier .ipa archive de l’application publiée (référencé ci-dessous en tant que
<path-to-ipa>
).
- Nom de l’application (référencé ci-dessous en tant que
Obtenez votre ID d’appareil physique (référencé ci-dessous en tant que
<device-identifier>
) :xcrun devicectl list devices
Installez l’application sur votre appareil physique :
xcrun devicectl device install app --device <device-identifier> <path-to-ipa>
Lancez l’application sur votre appareil physique :
xcrun devicectl device process launch --device <device-identifier> --start-stopped <bundle-identifier>
Ouvrez
lldb
et connectez-vous à votre appareil physique :(lldb) device select <device-identifier> (lldb) device process attach -n <app-name>
Une fois ces étapes terminées, vous pourrez commencer à déboguer votre application IOS .NET .NET native avec lldb
.
Importance du fichier de symboles
Par défaut, les symboles de débogage sont supprimés du fichier binaire de l’application dans un fichier .dSYM . Ce fichier est utilisé par les débogueurs et les outils d’analyse post mortem pour afficher des informations sur les variables locales, les numéros de ligne source et pour recréer les traces de pile des vidages sur incident. Par conséquent, il est essentiel de conserver le fichier de symboles avant de soumettre votre application à l’App Store.
Profilage du processeur
Xcode Instruments peut être utilisé pour collecter des exemples d’UC d’une application AOT native.
Analyse de tas
L’analyse du tas n’est actuellement pas prise en charge avec L’AOT natif.