Compartir a través de


Novedades de .NET MAUI para .NET 9

El enfoque de la interfaz de usuario de aplicaciones multiplataforma de .NET (.NET MAUI) en .NET 9 es mejorar la calidad del producto. Esto incluye la expansión de la cobertura de pruebas, las pruebas de escenario de un extremo a otro y la corrección de errores. Para obtener más información sobre las mejoras de calidad del producto en NET MAUI 9, consulta estas notas de la versión:

Importante

Debido al trabajo con dependencias externas, como Xcode o Android SDK Tools, la directiva de compatibilidad de .NET MAUI difiere de la directiva de compatibilidad de .NET y .NET Core. Para obtener más información, consulta la directiva de soporte técnico de .NET MAUI .

Se requiere compatibilidad con Xcode 16, que incluye compatibilidad con SDK para iOS 18, iPadOS 18, tvOS 18 y macOS 15, al compilar con .NET MAUI 9. Xcode 16 requiere un equipo Mac que ejecute macOS 14.5 o posterior.

En .NET 9, .NET MAUI se distribuye como una carga de trabajo de .NET y varios paquetes NuGet. La ventaja de este enfoque es que permite anclar fácilmente los proyectos a versiones específicas, a la vez que te permite obtener una vista previa sencilla de compilaciones no publicadas o experimentales. Al crear un nuevo proyecto .NET MAUI, los paquetes NuGet necesarios se agregan automáticamente al proyecto.

Objetivos mínimos de implementación

.NET MAUI 9 requiere objetivos de implementación mínimos de iOS 12.2 y Mac Catalyst 15.0 (macOS 12.0). Los destinos mínimos de implementación de Android y Windows siguen siendo los mismos. Para más información, consulta Plataformas compatibles con aplicaciones .NET MAUI.

Controles nuevos

.NET MAUI 9 incluye dos nuevos controles.

Vista web híbrida

HybridWebView habilita el hospedaje de contenido HTML/JS/CSS arbitrario en una vista web y la comunicación entre el código de la vista web (JavaScript) y el código que hospeda la vista web (C#/.NET). Por ejemplo, si ya dispones de una aplicación de React JS, puedes hospedarla en una multiplataforma nativa de .NET MAUI y compilar el back-end de la aplicación mediante C# y .NET.

Para compilar una aplicación .NET MAUI con HybridWebView necesitas:

  • Contenido web de la aplicación, que consta de HTML estático, JavaScript, CSS, imágenes y otros archivos.
  • Un control HybridWebView como parte de la interfaz de usuario de la aplicación. Puedes hacerlo mediante una referencia a él en el XAML de la aplicación.
  • Código en el contenido web y en C#/.NET, que usa las API de la HybridWebView para enviar mensajes entre los dos componentes.

Toda la aplicación, incluido el contenido web, se empaqueta y se ejecuta localmente en un dispositivo y se puede publicar en las tiendas de aplicaciones correspondientes. El contenido web se hospeda en un control de vista web nativo y se ejecuta dentro del contexto de la aplicación. Cualquier parte de la aplicación puede acceder a servicios web externos, pero no es un requisito.

Para más información, consulta HybridWebView.

Barra de título para Windows

El control TitleBar proporciona la capacidad de agregar una barra de título personalizada a la aplicación en Windows:

Introducción a la barra de título de .NET MAUI.

Puedes establecer una TitleBar como el valor de la propiedad de la Window.TitleBar en cualquier TitleBar:

<Window.TitleBar>
    <TitleBar x:Name="TeamsTitleBar"
              Title="Hello World"
              Icon="appicon.png"
              HeightRequest="46">
        <TitleBar.Content>
            <SearchBar Placeholder="Search"
                       PlaceholderColor="White"
                       MaximumWidthRequest="300"
                       HorizontalOptions="Fill"
                       VerticalOptions="Center" />
        </TitleBar.Content>
    </TitleBar>
</Window.TitleBar>

Un ejemplo de su uso en C# es:

Window window = new Window
{
    TitleBar = new TitleBar
    {
        Icon = "titlebar_icon.png"
        Title = "My App",
        Subtitle = "Demo"
        Content = new SearchBar { ... }      
    }
};

Una TitleBar es altamente personalizable a través de las propiedades del Content, el LeadingContent y el TrailingContent :

<TitleBar Title="My App"
          BackgroundColor="#512BD4"
          HeightRequest="48">
    <TitleBar.Content>
        <SearchBar Placeholder="Search"
                   MaximumWidthRequest="300"
                   HorizontalOptions="Fill"
                   VerticalOptions="Center" />
    </TitleBar.Content>
    <TitleBar.TrailingContent>
        <ImageButton HeightRequest="36"
                     WidthRequest="36"
                     BorderWidth="0"
                     Background="Transparent">
            <ImageButton.Source>
                <FontImageSource Size="16"
                                 Glyph="&#xE713;"
                                 FontFamily="SegoeMDL2"/>
            </ImageButton.Source>
        </ImageButton>
    </TitleBar.TrailingContent>
</TitleBar>

En la captura de pantalla siguiente se muestra el resultado de la apariencia:

Captura de pantalla de la barra de título de .NET MAUI.

Nota:

El control de la TitleBar será compatible con Mac Catalyst en una versión futura.

Para obtener más información, vea TitleBar.

Mejoras de control

.NET MAUI 9 incluye mejoras de control.

Modo de enlace BackButtonBehavior OneWay

El modo de enlace para IsVisible y IsEnabled en un BackButtonBehavior en una aplicación de Shell ahora es BindingMode.OneWay en lugar de BindingMode.OneTime. De este modo, puedes controlar más fácilmente el comportamiento del botón Atrás en runtime, con enlaces de datos:

<ContentPage ...>    
    <Shell.BackButtonBehavior>
        <BackButtonBehavior Command="{Binding BackCommand}"
                            IsVisible="{Binding IsBackButtonVisible}"
                            IconOverride="back.png" />   
    </Shell.BackButtonBehavior>
    ...
</ContentPage>

BlazorWebView

En iOS y Mac Catalyst 18, .NET MAUI 9 cambia el comportamiento predeterminado para hospedar contenido de un BlazorWebView a un localhost. La dirección interna 0.0.0.1 se usa para hospedar el contenido que ya no funciona y, como resultado, BlazorWebView no carga ningún contenido y se representa como un rectángulo vacío.

Para participar en el uso de la 0.0.0.1 dirección, agrega el código siguiente al método CreateMauiApp en MauiProgram.cs:

// Set this switch to use the LEGACY behavior of always using 0.0.0.1 to host BlazorWebView
AppContext.SetSwitch("BlazorWebView.AppHostAddressAlways0000", true);

Si encuentras bloqueos en Android con BlazorWebView, debes habilitar un modificador AppContext en el método CreateMauiApp en tu clase MauiProgram:

AppContext.SetSwitch("BlazorWebView.AndroidFireAndForgetAsync", true);

Este modificador permite a BlazorWebView activar y olvidar la eliminación asincrónica que se produce y, como resultado, corrige la mayoría de los interbloqueos de eliminación que se producen en Android. Para obtener más información, consulta Corrección de interbloqueos de eliminación en Android.

Botones en iOS

Button Los controles de iOS ahora respetan el espaciado, el relleno, el ancho del borde y los márgenes con mayor precisión que en las versiones anteriores. Ahora se cambiará el tamaño de una imagen Button grande al tamaño máximo, teniendo en cuenta el espaciado, el espaciado, el ancho del borde y los márgenes. Sin embargo, si contiene Button texto y una imagen, es posible que no sea posible ajustar todo el contenido dentro del botón, por lo que debe ajustar manualmente la imagen para lograr el diseño deseado.

CollectionView y CarouselView

.NET MAUI 9 incluye dos nuevos controladores opcionales en iOS y Mac Catalyst que aportan mejoras de rendimiento y estabilidad a CollectionView y CarouselView. Estos controladores se basan en las API de UICollectionView.

Para utilizar estos controladores, agrega el código siguiente a la clase MauiProgram:

#if IOS || MACCATALYST
builder.ConfigureMauiHandlers(handlers =>
{
    handlers.AddHandler<Microsoft.Maui.Controls.CollectionView, Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2>();
    handlers.AddHandler<Microsoft.Maui.Controls.CarouselView, Microsoft.Maui.Controls.Handlers.Items2.CarouselViewHandler2>();
});
#endif

ContentPage

En .NET MAUI 9, la propiedad HideSoftInputOnTapped también se admite en Mac Catalyst, así como Android e iOS.

Compatibilidad con la entrada de teclado flexible

.NET MAUI 9 agrega una nueva compatibilidad con la entrada de teclado flexible para Password, Date y Time. Se pueden habilitar en los controles Editor y Entry:

<Entry Keyboard="Date" />

Text alignment

La enumeración TextAlignment agrega un miembro Justify que se puede usar para alinear texto en controles de texto. Por ejemplo, puedes alinear horizontalmente el texto de Label con HorizontalTextAlignment.Justify:

<Label Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. In facilisis nulla eu felis fringilla vulputate."
       HorizontalTextAlignment="Justify"/>

TimePicker

TimePicker obtiene un evento TimeSelected, que se genera cuando cambia la hora seleccionada. El objeto TimeChangedEventArgs que acompaña al evento TimeSelected tiene propiedades NewTime y OldTime, que especifican la hora nueva y antigua, respectivamente.

WebView

WebView agrega un evento de ProcessTerminated que se genera cuando un proceso de WebView finaliza inesperadamente. El objeto WebViewProcessTerminatedEventArgs que acompaña a este evento define propiedades específicas de la plataforma que indican por qué se produjo un error en el proceso.

Enlaces compilados en código

Los enlaces escritos en código suelen usar rutas de acceso de cadena que se resuelven en tiempo de ejecución con reflexión y la sobrecarga de hacerlo varía de una plataforma a otra plataforma. .NET MAUI 9 presenta un método de extensión SetBinding adicional que define enlaces mediante un argumento Func en lugar de una ruta de acceso de cadena:

// in .NET 8
MyLabel.SetBinding(Label.TextProperty, "Text");

// in .NET 9
MyLabel.SetBinding(Label.TextProperty, static (Entry entry) => entry.Text);

Este enfoque de enlace compilado proporciona las ventajas siguientes:

  • Mejora del rendimiento del enlace de datos mediante la resolución de expresiones de enlace en tiempo de compilación, en lugar de en tiempo de ejecución.
  • Una mejor experiencia de solución de problemas para el desarrollador, ya que los enlaces no válidos se notifican como errores de compilación.
  • IntelliSense durante la edición.

No todos los métodos se pueden usar para definir un enlace compilado. La expresión debe ser una expresión de acceso de propiedad simple. En los ejemplos siguientes se muestran expresiones de enlace válidas y no válidas:

// Valid: Property access
static (PersonViewModel vm) => vm.Name;
static (PersonViewModel vm) => vm.Address?.Street;

// Valid: Array and indexer access
static (PersonViewModel vm) => vm.PhoneNumbers[0];
static (PersonViewModel vm) => vm.Config["Font"];

// Valid: Casts
static (Label label) => (label.BindingContext as PersonViewModel).Name;
static (Label label) => ((PersonViewModel)label.BindingContext).Name;

// Invalid: Method calls
static (PersonViewModel vm) => vm.GetAddress();
static (PersonViewModel vm) => vm.Address?.ToString();

// Invalid: Complex expressions
static (PersonViewModel vm) => vm.Address?.Street + " " + vm.Address?.City;
static (PersonViewModel vm) => $"Name: {vm.Name}";

Además, .NET MAUI 9 agrega un método BindingBase.Create que establece el enlace directamente en el objeto con una Func y devuelve la instancia del objeto de enlace:

// in .NET 8
myEntry.SetBinding(Entry.TextProperty, new MultiBinding
{
    Bindings = new Collection<BindingBase>
    {
        new Binding(nameof(Entry.FontFamily), source: RelativeBindingSource.Self),
        new Binding(nameof(Entry.FontSize), source: RelativeBindingSource.Self),
        new Binding(nameof(Entry.FontAttributes), source: RelativeBindingSource.Self),
    },
    Converter = new StringConcatenationConverter()
});

// in .NET 9
myEntry.SetBinding(Entry.TextProperty, new MultiBinding
{
    Bindings = new Collection<BindingBase>
    {
        Binding.Create(static (Entry entry) => entry.FontFamily, source: RelativeBindingSource.Self),
        Binding.Create(static (Entry entry) => entry.FontSize, source: RelativeBindingSource.Self),
        Binding.Create(static (Entry entry) => entry.FontAttributes, source: RelativeBindingSource.Self),
    },
    Converter = new StringConcatenationConverter()
});

Importante

Los enlaces compilados son necesarios en lugar de enlaces basados en cadenas en aplicaciones NativeAOT y en aplicaciones con recorte completo habilitado.

Enlaces compilados en XAML

En .NET MAUI 8, los enlaces compilados están deshabilitados para cualquier expresión de enlace XAML que defina la propiedad Source y no se admita en varios enlaces. Estas restricciones se han quitado en .NET MAUI 9. Para obtener información sobre la compilación de expresiones de enlace XAML que definen la Source propiedad, consulta Compilar enlaces que definen la Source propiedad.

De forma predeterminada, .NET MAUI 9 genera advertencias de compilación para los enlaces que no usan enlaces compilados. Para obtener más información sobre las advertencias de enlaces compilados XAML, consulta Advertencias de enlaces compilados XAML.

Inserción de dependencia

En una aplicación de Shell, ya no es necesario registrar las páginas con el contenedor de inserción de dependencias a menos que quiera influir en la duración de la página en relación con el contenedor con los AddSingletonmétodos , AddTransiento AddScoped . Para obtener más información sobre estos métodos, consulte Duración de dependencias.

Desconexión del controlador

Al implementar un control personalizado mediante controladores, cada implementación del controlador de plataforma debe utilizar el método DisconnectHandler() para realizar cualquier limpieza de vista nativa, como anular la suscripción de eventos. Sin embargo, antes de .NET MAUI 9, .NET MAUI no invoca la implementación de DisconnectHandler() intencionadamente. En su lugar, tendrías que invocarlo tú mismo al elegir limpiar un control, como al navegar hacia atrás en una aplicación.

En .NET MAUI 9, los controladores se desconectan automáticamente de sus controles siempre que es posible, como al navegar hacia atrás en una aplicación. En algunas situaciones, es posible que no desees este comportamiento. Por lo tanto, .NET MAUI 9 agrega una propiedad adjunta de HandlerProperties.DisconnectPolicy para controlar cuándo los controladores se desconectan de sus controles. Esta propiedad requiere un HandlerDisconnectPolicy argumento, con la enumeración que define los siguientes valores:

  • Automatic, que indica que los controladores se desconectarán automáticamente. Se trata del valor predeterminado de la propiedad adjunta HandlerProperties.DisconnectPolicy.
  • Manual, que indica que los controladores tendrán que desconectarse manualmente invocando la implementación de DisconnectHandler().

En el ejemplo siguiente se muestra cómo establecer la propiedad adjunta de HandlerProperties.DisconnectPolicy:

<controls:Video x:Name="video"
                HandlerProperties.DisconnectPolicy="Manual"
                Source="video.mp4"
                AutoPlay="False" />

El código de C# equivalente es el siguiente:

Video video = new Video
{
    Source = "video.mp4",
    AutoPlay = false
};
HandlerProperties.SetDisconnectPolicy(video, HandlerDisconnectPolicy.Manual);

Además, hay un método de extensión de DisconnectHandlers que desconecta los controladores de un determinado IView:

video.DisconnectHandlers();

Al desconectarlo, el método de DisconnectHandlers propagará el árbol de control hasta que se complete o llegue a un control que haya establecido una directiva manual.

Compatibilidad con varias ventanas

.NET MAUI 9 agrega la capacidad de traer una ventana específica al frente en Mac Catalyst y Windows con el método Application.Current.ActivateWindow:

Application.Current?.ActivateWindow(windowToActivate);

Implementación de AOT nativo

En .NET MAUI 9 puede participar en la implementación nativa de AOT en iOS y Mac Catalyst. La implementación de AOT nativa genera una aplicación MAUI de .NET que se ha compilado con antelación (AOT) en código nativo. Esto produce las siguientes ventajas:

  • Tamaño reducido del paquete de la aplicación, normalmente hasta 2,5x más pequeños.
  • Tiempo de inicio más rápido, normalmente hasta 2 veces más rápido.
  • Tiempo de compilación más rápido.

Para obtener más información, consulte Implementación nativa de AOT en iOS y Mac Catalyst.

Incrustación nativa

.NET MAUI 9 incluye API completas para situaciones de inserción nativas, que anteriormente tenían que agregarse manualmente al proyecto:

var mauiApp = MauiProgram.CreateMauiApp();

#if ANDROID
var mauiContext = new MauiContext(mauiApp.Services, window);
#else
var mauiContext = new MauiContext(mauiApp.Services);
#endif

var mauiView = new MyMauiContent();
var nativeView = mauiView.ToPlatform(mauiContext);

Como alternativa, puedes usar el método ToPlatformEmbedded, pasando en Window para la plataforma en la que se ejecuta la aplicación:

var mauiApp = MauiProgram.CreateMauiApp();
var mauiView = new MyMauiContent();
var nativeView = mauiView.ToPlatformEmbedded(mauiApp, window);

En ambos ejemplos, nativeView es una versión específica de la plataforma de mauiView.

Para arrancar una aplicación nativa integrada en .NET MAUI 9, llama al método de extensión UseMauiEmbeddedApp en el objeto MauiAppBuilder:

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();

        builder
            .UseMauiEmbeddedApp<App>();

        return builder.Build();
    }
}

Para obtener más información, consulta Inserción nativa.

Plantillas de proyecto

.NET MAUI 9 agrega una plantilla de proyecto .NET MAUI Blazor Hybrid y aplicación web a Visual Studio, que crea una solución con una aplicación .NET MAUI Blazor Hybrid con una aplicación web Blazor, que comparte un código común en una biblioteca de clases Razor.

La plantilla también se puede usar desde dotnew new:

dotnet new maui-blazor-web -n AllTheTargets

Diccionarios de recursos

En .NET MAUI 9, un XAML ResourceDictionary independiente (que no está respaldado por un archivo de código subyacente) tiene como valor predeterminado tener su XAML compilado. Para no participar en este comportamiento, especifica <?xaml-comp compile="false" ?> después del encabezado XML.

Recorte

Ahora se admite el recorte completo estableciendo la $(TrimMode) propiedad fullMSBuild en . Para obtener más información, consulte Recorte de una aplicación MAUI de .NET.

Incompatibilidades de recorte

Las siguientes características de .NET MAUI no son compatibles con el recorte completo y el recortador lo quitará:

Recorte de modificadores de características

.NET MAUI tiene directivas de optimizador, conocidas como modificadores de características, que permiten conservar el código de las características que no son seguras. Estas directivas de optimizador se pueden usar cuando la $(TrimMode) propiedad build está establecida fullen , así como para NativeAOT:

Propiedad de MSBuild Descripción
MauiEnableVisualAssemblyScanning Cuando se establece en true, .NET MAUI examinará los ensamblados para los tipos que implementan IVisual y para los atributos [assembly:Visual(...)], y registrará estos tipos. De manera predeterminada, esta propiedad de compilación está establecida en false.
MauiShellSearchResultsRendererDisplayMemberNameSupported Cuando se establece en false, se ignorará el valor de SearchHandler.DisplayMemberName. En su lugar, debes proporcionar un ItemTemplate para definir la apariencia de los resultados SearchHandler. De manera predeterminada, esta propiedad de compilación está establecida en true.
MauiQueryPropertyAttributeSupport Cuando se establece en false, los atributos [QueryProperty(...)] no se usarán para establecer valores de propiedad al navegar. En su lugar, debes implementar la interfaz IQueryAttributable para aceptar parámetros de consulta. De manera predeterminada, esta propiedad de compilación está establecida en true.
MauiImplicitCastOperatorsUsageViaReflectionSupport Cuando se establece en false, .NET MAUI no buscará operadores de conversión implícitos al convertir valores de un tipo a otro. Esto puede afectar a los enlaces entre propiedades con distintos tipos y establecer un valor de propiedad de un objeto enlazable con un valor de un tipo diferente. En su lugar, debes definir un TypeConverter para el tipo y adjuntarlo al tipo mediante el atributo TypeConverterAttribute. De manera predeterminada, esta propiedad de compilación está establecida en true.
_MauiBindingInterceptorsSupport Cuando se establece en false, .NET MAUI no intercepta ninguna llamada a los métodos SetBinding y no intentará compilarlas. De manera predeterminada, esta propiedad de compilación está establecida en true.
MauiEnableXamlCBindingWithSourceCompilation Cuando se establece en true, .NET MAUI compilará todos los enlaces, incluidos los donde se usa la Source propiedad . Si habilita esta característica, asegúrese de que todos los enlaces tengan el valor correcto x:DataType para que se compilen o borren el tipo de datos con x:Data={x:Null}} si el enlace no se debe compilar. De forma predeterminada, esta propiedad de compilación solo se establece en true cuando se habilita el recorte completo o la implementación de AOT nativa.

Estas propiedades de MSBuild también tienen modificadores equivalentes AppContext :

  • La MauiEnableVisualAssemblyScanning propiedad MSBuild tiene un modificador equivalente AppContext denominado Microsoft.Maui.RuntimeFeature.IsIVisualAssemblyScanningEnabled.
  • La MauiShellSearchResultsRendererDisplayMemberNameSupported propiedad MSBuild tiene un modificador equivalente AppContext denominado Microsoft.Maui.RuntimeFeature.IsShellSearchResultsRendererDisplayMemberNameSupported.
  • La MauiQueryPropertyAttributeSupport propiedad MSBuild tiene un modificador equivalente AppContext denominado Microsoft.Maui.RuntimeFeature.IsQueryPropertyAttributeSupported.
  • La MauiImplicitCastOperatorsUsageViaReflectionSupport propiedad MSBuild tiene un modificador equivalente AppContext denominado Microsoft.Maui.RuntimeFeature.IsImplicitCastOperatorsUsageViaReflectionSupported.
  • La _MauiBindingInterceptorsSupport propiedad MSBuild tiene un modificador equivalente AppContext denominado Microsoft.Maui.RuntimeFeature.AreBindingInterceptorsSupported.
  • La MauiEnableXamlCBindingWithSourceCompilation propiedad MSBuild tiene un modificador equivalente AppContext denominado Microsoft.Maui.RuntimeFeature.MauiEnableXamlCBindingWithSourceCompilationEnabled.

La manera más fácil de consumir un modificador de características es colocar la propiedad de MSBuild correspondiente en el archivo de proyecto de la aplicación (*.csproj), lo que hace que el código relacionado se recorte de los ensamblados MAUI de .NET.

Implementación de aplicaciones de Windows

Al depurar e implementar un nuevo proyecto MAUI de .NET en Windows, el comportamiento predeterminado en .NET MAUI 9 es implementar una aplicación desempaquetada. Para obtener más información, consulta Implementación y depuración de la aplicación .NET MAUI en Windows.

Códigos de error del compilador XAML

En .NET MAUI 9, los códigos de error del compilador XAML han cambiado su prefijo de XFC a XC. Asegúrese de actualizar las propiedades de compilación , $(WarningsNotAsErrors)y $(NoWarn) en los $(WarningsAsErrors)archivos de proyecto de la aplicación, si se usa, para hacer referencia al nuevo prefijo.

Extensiones de marcado XAML

Todas las clases que implementan IMarkupExtension, IMarkupExtension<T>, IValueProvider y IExtendedTypeConverter deben anotarse con RequireServiceAttribute o AcceptEmptyServiceProviderAttribute. Esto es necesario debido a una optimización del compilador XAML introducida en .NET MAUI 9 que permite la generación de código más eficaz, lo que ayuda a reducir el tamaño de la aplicación y a mejorar el rendimiento del tiempo de ejecución.

Para obtener información sobre cómo anotar extensiones de marcado con estos atributos, consulta Proveedores de servicios.

Sincronización de Xcode

.NET MAUI 9 incluye la sincronización de Xcode (xcsync), que es una herramienta que permite usar Xcode para administrar archivos específicos de Apple con proyectos de .NET, incluidos catálogos de recursos, archivos plist, guiones gráficos y archivos xib. La herramienta tiene dos comandos principales para generar un proyecto de Xcode temporal a partir de un proyecto de .NET y para sincronizar los cambios de los archivos Xcode de nuevo en el proyecto de .NET.

Usa dotnet build con los comandos xcsync-generate o xcsync-sync para generar o sincronizar estos archivos y pase un archivo de proyecto y argumentos adicionales:

dotnet build /t:xcsync-generate
    /p:xcSyncProjectFile=<PROJECT>
    /p:xcSyncXcodeFolder=<TARGET_XCODE_DIRECTORY>
    /p:xcSyncTargetFrameworkMoniker=<FRAMEWORK>
    /p:xcSyncVerbosity=<LEVEL>

Para obtener más información, consulta sincronización de Xcode.

Interfaces API desusadas

.NET MAUI 9 deja obsoletas algunas API, que se eliminarán completamente en una versión futura.

Marco

El control Frame se marca como obsoleto en .NET MAUI 9 y se eliminará completamente en una versión futura. El control Border debe usarse en su lugar. Para más información, consulta Borde.

MainPage

En lugar de definir la primera página de la aplicación mediante la propiedad MainPage en un objeto Application, debes establecer la propiedad Page en una Window en la primera página de la aplicación. Esto es lo que sucede internamente en .NET MAUI cuando se establece la propiedad MainPage, por lo que no hay ningún cambio de comportamiento introducido por la propiedad MainPage que se marca como obsoleta.

En el siguiente ejemplo se muestra cómo establecer la propiedad Page en un objeto Window a través de la invalidación de CreateWindow:

public partial class App : Application
{
    public App()
    {
        InitializeComponent();
    }

    protected override Window CreateWindow(IActivationState? activationState)
    {
        return new Window(new AppShell());
    }
}

El código que tiene acceso a la Application.Current.MainPage propiedad ahora debe tener acceso a la Application.Current.Windows[0].Page propiedad para las aplicaciones con una sola ventana. En el caso de las aplicaciones con varias ventanas, use la Application.Current.Windows colección para identificar la ventana correcta y, a continuación, acceder a la Page propiedad . Además, cada elemento cuenta con una Window propiedad, a la que se puede acceder cuando el elemento forma parte de la ventana actual, desde la que se puede tener acceso a la Page propiedad (Window.Page). El código de plataforma puede recuperar el objeto de IWindow la aplicación con el método de Microsoft.Maui.Platform.GetWindow extensión.

Aunque la MainPage propiedad se conserva en .NET MAUI 9, se quitará completamente en una versión futura.

Diseños de compatibilidad

Las clases de diseño de compatibilidad del espacio de nombres Microsoft.Maui.Controls.Compatibility han quedado obsoletas.

Llamadas de medida heredadas

Los siguientes VisualElement métodos de medida han quedado obsoletos:

Se trata de métodos de medida heredados que no funcionan correctamente con las expectativas de diseño de MAUI de .NET.

Como reemplazo, se ha introducido el VisualElement.Measure(Double, Double) método . Este método de devuelve el tamaño mínimo que un elemento necesita para mostrarse en el dispositivo. Los márgenes se excluyen de la medida, pero se indican con el tamaño. Este es el método preferido para medir una vista.

Además, la estructura SizeRequest está obsoleta. En su lugar, se debe usar Size.

Actualización de .NET 8 a .NET 9

Para actualizar los proyectos de .NET MAUI de .NET 8 a .NET 9, instale primero .NET 9 y la carga de trabajo de MAUI de .NET con Visual Studio 17.12 o con Visual Studio Code y la extensión .NET MAUI y .NET y las cargas de trabajo de .NET MAUI, o con el instalador independiente y el dotnet workload install maui comando.

Actualización del archivo del proyecto

Para actualizar la aplicación .NET MAUI de .NET 8 a .NET 9, abra el archivo de proyecto de la aplicación (.csproj) y cambie target Framework Monikers (TFMs) de 8 a 9. Si usa un TFM, como net8.0-ios15.2, asegúrate de que coincida con la versión de la plataforma o elimínalo por completo. En el ejemplo siguiente se muestran los TFM para un proyecto de .NET 8:

<TargetFrameworks>net8.0-android;net8.0-ios;net8.0-maccatalyst;net8.0-tizen</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net8.0-windows10.0.19041.0</TargetFrameworks>

En el ejemplo siguiente se muestran los TFM para un proyecto de .NET 9:

<TargetFrameworks>net9.0-android;net9.0-ios;net9.0-maccatalyst;net9.0-tizen</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net9.0-windows10.0.19041.0</TargetFrameworks>

Si el archivo de proyecto de la aplicación hace referencia a una versión de .NET 8 del Microsoft.Maui.Controls paquete NuGet, ya sea directamente o a través de la $(MauiVersion) propiedad de compilación, actualícela a una versión de .NET 9. A continuación, quite la referencia de paquete para el Microsoft.Maui.Controls.Compatibility paquete NuGet, siempre que la aplicación no use ningún tipo de este paquete. Además, actualice la referencia de paquete del Microsoft.Extensions.Logging.Debug paquete NuGet a la versión más reciente de .NET 9.

Si la aplicación tiene como destino iOS o Mac Catalyst, actualice las $(SupportedOSPlatformVersion) propiedades de compilación de estas plataformas a 15.0:

<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">15.0</SupportedOSPlatformVersion>

Al depurar e implementar un nuevo proyecto MAUI de .NET en Windows, el comportamiento predeterminado en .NET 9 es implementar una aplicación sin empaquetar. Para adoptar este comportamiento, consulte Conversión de una aplicación .NET MAUI de Windows empaquetada en desempaquetada.

Antes de compilar la aplicación actualizada por primera vez, elimina las carpetas bin y obj. Los errores y advertencias de compilación le guiarán hacia los pasos siguientes.

Actualizar códigos de error del compilador XAML

Los códigos de error del compilador XAML han cambiado su prefijo de XFC a XC, por lo que actualiza las propiedades , $(WarningsNotAsErrors)y $(NoWarn) compila en el $(WarningsAsErrors)archivo de proyecto de la aplicación, si se usa, para hacer referencia al nuevo prefijo.

Direccione las nuevas advertencias del compilador XAML para los enlaces compilados

Las advertencias de compilación se generarán para los enlaces que no usan enlaces compilados y que deberán solucionarse. Para obtener más información, consulta Advertencias de enlaces compilados xaml.

Actualizar extensiones de marcado XAML

Las extensiones de marcado XAML deberán anotarse con o RequireServiceAttribute AcceptEmptyServiceProviderAttribute. Esto es necesario debido a una optimización del compilador XAML que permite la generación de código más eficaz, lo que ayuda a reducir el tamaño de la aplicación y mejorar el rendimiento en tiempo de ejecución. Para más información, consulta Proveedores de servicios.

API en desuso de direcciones

.NET MAUI 9 deja obsoletas algunas API, que se eliminarán completamente en una versión futura. Por lo tanto, solucione las advertencias de compilación sobre las API en desuso. Para más información, consulte API en desuso.

Adopción de enlaces compilados que establecen la propiedad Source

Puede optar por compilar enlaces que establezcan la Source propiedad para aprovechar el mejor rendimiento en tiempo de ejecución. Para obtener más información, vea Compilar enlaces que definen la Source propiedad .

Adopción de enlaces compilados en C#

Puede optar por compilar expresiones de enlace declaradas en código para aprovechar el mejor rendimiento en tiempo de ejecución. Para obtener más información, consulte Enlaces compilados en el código.

Adopción del recorte completo

Puede adoptar para usar el recorte completo para reducir el tamaño general de la aplicación estableciendo la $(TrimMode) propiedad fullMSBuild en . Para obtener más información, consulte Recorte de una aplicación MAUI de .NET.

Adopción de la implementación de NativeAOT en plataformas compatibles

Puede participar en la implementación nativa de AOT en iOS y Mac Catalyst. La implementación de AOT nativa genera una aplicación MAUI de .NET que se ha compilado con antelación (AOT) en código nativo. Para obtener más información, consulte Implementación nativa de AOT en iOS y Mac Catalyst.

.NET para Android

.NET para Android en .NET 9, que agrega compatibilidad con la API 35, incluye trabajo para reducir los tiempos de compilación y mejorar la capacidad de recorte de las aplicaciones para reducir el tamaño y mejorar el rendimiento. Para obtener más información sobre .NET para Android en .NET 9, consulte las notas de la versión siguientes:

Paquetes de recursos

.NET para Android en .NET 9 presenta la capacidad de colocar recursos en un paquete independiente, conocido como un paquete de recursos. Esto te permite cargar juegos y aplicaciones que normalmente serían mayores que el tamaño de paquete básico permitido por Google Play. Al colocar estos recursos en un paquete independiente, obtiene la capacidad de cargar un paquete que tiene un tamaño de hasta 2 Gb, en lugar del tamaño básico de paquete de 200 Mb.

Importante

Los paquetes de recursos solo pueden contener recursos. En el caso de .NET para Android, esto significa que los elementos que tienen la acción de compilación AndroidAsset.

Las aplicaciones MAUI de .NET definen los recursos a través de la acción de compilación MauiAsset. Un paquete de recursos se puede especificar mediante el atributo AssetPack:

<MauiAsset
    Include="Resources\Raw\**"
    LogicalName="%(RecursiveDir)%(Filename)%(Extension)"
    AssetPack="myassetpack" />

Nota:

Otras plataformas omitirán los metadatos adicionales.

Si tienes elementos específicos que deseas colocar en un paquete de recursos, puedes usar el atributo Update para definir metadatos AssetPack:

<MauiAsset Update="Resources\Raw\MyLargeAsset.txt" AssetPack="myassetpack" />

Los paquetes de recursos pueden tener diferentes opciones de entrega, que controlan cuándo se instalarán los recursos en el dispositivo:

  • Los paquetes de tiempo de instalación se instalan al mismo tiempo que la aplicación. Este tipo de paquete puede tener un tamaño de hasta 1 Gb, pero solo puede tener uno de ellos. Este tipo de entrega se especifica con metadatos InstallTime.
  • Los paquetes de seguimiento rápido se instalarán en algún momento poco después de que la aplicación haya terminado de instalarse. La aplicación podrá iniciarse mientras se instala este tipo de paquete, por lo que debe comprobar que ha terminado de instalarse antes de intentar usar los recursos. Este tipo de paquete de activos puede tener un tamaño de hasta 512 Mb. Este tipo de entrega se especifica con metadatos FastFollow.
  • Los paquetes a petición nunca se descargarán en el dispositivo a menos que la aplicación lo solicite específicamente. El tamaño total de todos los paquetes de recursos no puede superar los 2 Gb y puede tener hasta 50 paquetes de activos independientes. Este tipo de entrega se especifica con metadatos OnDemand.

En las aplicaciones MAUI de .NET, el tipo de entrega se puede especificar con el atributo DeliveryType en un MauiAsset:

<MauiAsset Update="Resources\Raw\myvideo.mp4" AssetPack="myassetpack" DeliveryType="FastFollow" />

Para más información sobre los paquetes de recursos de Android, consulta Paquetes de recursos de Android.

Compatibilidad con Android 15

.NET para Android en .NET 9 agrega enlaces .NET para Android 15 (API 35). Para compilar para estas API, actualice la plataforma de destino del proyecto a net9.0-android:

<TargetFramework>net9.0-android</TargetFramework>

Nota:

También puede especificar net9.0-android35 como marco de destino, pero el número 35 probablemente cambiará en futuras versiones de .NET para que coincidan con las versiones más recientes del sistema operativo Android.

Arquitecturas de 64 bits de forma predeterminada

.NET para Android en .NET 9 ya no compila los siguientes identificadores en tiempo de ejecución (RID) de forma predeterminada:

  • android-arm
  • android-x86

Esto debe mejorar los tiempos de compilación y reducir el tamaño de los archivos Android .apk . Tenga en cuenta que Google Play admite la división de agrupaciones de aplicaciones por arquitectura.

Si necesita compilar para estas arquitecturas, puede agregarlas al archivo de proyecto (.csproj):

<RuntimeIdentifiers>android-arm;android-arm64;android-x86;android-x64</RuntimeIdentifiers>

O bien, en un proyecto de destino múltiple:

<RuntimeIdentifiers Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">android-arm;android-arm64;android-x86;android-x64</RuntimeIdentifiers>

Métodos de serialización de Android

Las mejoras en los métodos de serialización de Android en .NET 9 han hecho que la característica funcione de forma más confiable en las aplicaciones, pero aún no es el valor predeterminado. La habilitación de esta característica ha dado lugar a una mejora aproximada del 10 % en el rendimiento de una aplicación de prueba.

Los métodos de serialización de Android se pueden habilitar en el archivo de proyecto (.csproj) mediante la $(AndroidEnableMarshalMethods) propiedad :

<PropertyGroup>
    <AndroidEnableMarshalMethods>true</AndroidEnableMarshalMethods>
</PropertyGroup>

Para más información sobre la característica, consulte la documentación o la implementación de características en GitHub.

Mejoras de recorte

En .NET 9, los ensamblados de api de Android (Mono.Android.dll, Java.Interop.dll) ahora son totalmente compatibles. Para participar en el recorte completo, establezca la propiedad en el $(TrimMode) archivo del proyecto (.csproj):

<PropertyGroup>
    <TrimMode>Full</TrimMode>
</PropertyGroup>

Esto también habilita los analizadores de recorte, de modo que se introduzcan advertencias para cualquier código de C# problemático.

Para más información, consulte Recorte de granularidad.

.NET para iOS

.NET 9 en iOS, tvOS, Mac Catalyst y macOS usa Xcode 16.0 para las siguientes versiones de la plataforma:

  • iOS: 18.0
  • tvOS: 18.0
  • Mac Catalyst: 18.0
  • macOS: 15.0

Para más información sobre .NET 9 en iOS, tvOS, Mac Catalyst y macOS, consulta estas notas de la versión:

Enlaces

.NET para iOS 9 presenta la capacidad de usar versiones de varios destinos de .NET para enlaces iOS. Por ejemplo, un proyecto de biblioteca puede necesitar compilar para dos versiones distintas de iOS:

<TargetFrameworks>net9.0-ios17.0;net9.0-ios17.2</TargetFrameworks>

Esto generará dos bibliotecas, una con enlaces de iOS 17.0 y otra con enlaces de iOS 17.2.

Importante

Un proyecto de aplicación siempre debe tener como destino el SDK de iOS más reciente.

Mejoras de recorte

En .NET 9, los ensamblados de iOS y Mac Catalyst (Microsoft.iOS.dll, Microsoft.MacCatalyst.dll etc.) ahora son totalmente compatibles con el recorte. Para participar en el recorte completo, establezca la propiedad en el $(TrimMode) archivo del proyecto (.csproj):

<PropertyGroup>
    <TrimMode>Full</TrimMode>
</PropertyGroup>

Esto también habilita los analizadores de recorte, de modo que se introduzcan advertencias para cualquier código de C# problemático.

Para más información, consulte Recorte de granularidad.

AOT nativo para iOS y Mac Catalyst

En .NET para iOS 9, la compilación nativa de Ahead of Time (AOT) para iOS y Mac Catalyst aprovecha el recorte completo para reducir el tamaño del paquete y el rendimiento de inicio de la aplicación. NativeAOT se basa en el recorte completo, al participar en un nuevo entorno de ejecución.

Importante

La aplicación y sus dependencias deben ser totalmente recortables para poder usar esta característica.

NativeAOT requiere que las aplicaciones se compilan con advertencias de optimizador cero, con el fin de demostrar que la aplicación funcionará correctamente en tiempo de ejecución.

Consulte también