Novidades no .NET MAUI para .NET 9

O foco da .NET Multi-Platform App UI (.NET MAUI) no .NET 9 é melhorar a qualidade do produto. Isso inclui a expansão da cobertura de teste, o teste de cenário de ponta a ponta e a correção de bugs. Para obter mais informações sobre as melhorias na qualidade do produto no .NET MAUI 9, confira as seguintes notas de versão:

Importante

Devido ao trabalho com dependências externas, como Xcode ou Android SDK Tools, a política de suporte do .NET MAUI difere da política de suporte do .NET e do .NET Core. Para obter mais informações, consulte a política de suporte do .NET MAUI.

A compatibilidade com o Xcode 16, que inclui suporte a SDK para iOS 18, iPadOS 18, tvOS 18 e macOS 15, é necessária ao criar com o .NET MAUI 9. O Xcode 16 requer um Mac com macOS 14.5 ou posterior.

No .NET 9, o .NET MAUI é fornecido como uma carga de trabalho .NET e vários pacotes NuGet. A vantagem dessa abordagem é que ela permite que fixar facilmente seus projetos em versões específicas, além de visualizar facilmente builds não lançados ou experimentais. Quando você cria um novo projeto .NET MAUI, os pacotes NuGet necessários são adicionados automaticamente ao projeto.

Destinos mínimos de implantação

O .NET MAUI 9 requer os destinos mínimos de implantação iOS 12.2 e Mac Catalyst 15.0 (macOS 12.0). Os destinos mínimos de implantação do Android e do Windows permanecem os mesmos. Para obter mais informações, consulte plataformas com suporte para aplicativos .NET MAUI.

Novos controles

O .NET MAUI 9 inclui dois novos controles.

HybridWebView

HybridWebView permite hospedar conteúdo HTML/JS/CSS arbitrário em uma exibição web e permite a comunicação entre o código na exibição web (JavaScript) e o código que hospeda a exibição web (C#/.NET). Por exemplo, se você tiver um aplicativo React JS, poderá hospedá-lo em um aplicativo nativo .NET MAUI multiplataforma e criar o back-end do aplicativo usando C# e .NET.

Para criar um aplicativo .NET MAUI com HybridWebView, você precisa:

  • O conteúdo da Web do aplicativo, que consiste em HTML, JavaScript, CSS, imagens e outros arquivos estáticos.
  • Um HybridWebView controle como parte da interface do usuário do aplicativo. Isso pode ser feito referenciando-o no XAML do aplicativo.
  • Código no conteúdo da Web e em C#/.NET, que usa as HybridWebView APIs para enviar mensagens entre os dois componentes.

Todo o aplicativo, incluindo o conteúdo da Web, é empacotado e executado localmente em um dispositivo e pode ser publicado nas lojas de aplicativos aplicáveis. O conteúdo da Web é hospedado em um controle do modo de exibição da Web nativo e é executado no contexto do aplicativo. Qualquer parte do aplicativo pode acessar serviços Web externos, mas isso não é necessário.

Para obter mais informações, consulte HybridWebView.

Barra de título para o Windows

O controle TitleBar fornece a capacidade de adicionar uma barra de título personalizada ao seu aplicativo no Windows:

Visão geral da barra de título do .NET MAUI.

Um TitleBar pode ser definido como o valor da propriedade Window.TitleBar em qualquer 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>

Um exemplo de seu uso em C# é:

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

Um TitleBar é altamente personalizável por meio de suas propriedades Content, LeadingContent e 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>

A captura de tela a seguir mostra a aparência resultante:

Captura de tela da barra de título do .NET MAUI.

Observação

O suporte do Mac Catalyst para o controle TitleBar será adicionado em uma versão futura.

Para obter mais informações, consulte TitleBar.

Aprimoramentos de controle

O .NET MAUI 9 também inclui aprimoramentos de controle.

Modo de associação unidirecional BackButtonBehavior

O modo de associação para IsVisible e IsEnabled em um aplicativo Shell BackButtonBehavior agora é BindingMode.OneWay em vez de BindingMode.OneTime. Isso permite que você controle mais facilmente o comportamento do botão Voltar em runtime, com associações de dados:

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

BlazorWebView

No iOS e no Mac Catalyst 18, o .NET MAUI 9 altera o comportamento padrão para hospedar conteúdo em um BlazorWebView para localhost. O endereço interno 0.0.0.1 usado para hospedar o conteúdo não funciona mais e resulta no não carregamento de BlazorWebView de nenhum conteúdo e na renderização como um retângulo vazio.

Para optar por usar o endereço 0.0.0.1, adicione o seguinte código ao método CreateMauiApp em 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);

Se houver travamentos no Android com o BlazorWebView, você deve habilitar uma opção de AppContext no método CreateMauiApp na classe MauiProgram:

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

Essa opção permite que BlazorWebView dispare e esqueça o descarte assíncrono que ocorre e, como resultado, corrige a maioria dos deadlocks de descarte que ocorrem no Android. Para mais informações, consulte Corrigir deadlocks de descarte no Android.

Botões no iOS

Button Os controles no iOS agora respeitam o espaçamento, o preenchimento, a largura da borda e as margens com mais precisão do que nas versões anteriores. Uma imagem grande em um Button agora será redimensionada para o tamanho máximo, levando em consideração o espaçamento, o preenchimento, a largura da borda e as margens. No entanto, se a Button contiver texto e uma imagem, talvez não seja possível encaixar todo o conteúdo dentro do botão e, portanto, você deve dimensionar sua imagem manualmente para obter o layout desejado.

CollectionView e CarouselView

O .NET MAUI 9 inclui dois novos manipuladores opcionais no iOS e no Mac Catalyst que trazem melhorias de desempenho e estabilidade para CollectionView e CarouselView Esses manipuladores são baseados em APIs UICollectionView.

Para optar por usar esses manipuladores, adicione o seguinte código à sua classe 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

No .NET MAUI 9, a propriedade HideSoftInputOnTapped também tem suporte no Mac Catalyst, Android e iOS.

Suporte de entrada do teclado virtual

O .NET MAUI 9 adiciona novo suporte de entrada de teclado simples para Password, Date e Time. Eles podem ser habilitados em controles Editor e Entry:

<Entry Keyboard="Date" />

Alinhamento do texto

A enumeração TextAlignment adiciona um membro Justify que pode ser usado para alinhar texto em controles de texto. Por exemplo, você pode alinhar horizontalmente o texto em um Label com HorizontalTextAlignment.Justify:

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

TimePicker

TimePicker ganha um evento TimeSelected, que é gerado quando o tempo selecionado muda. O objeto TimeChangedEventArgs que acompanha o evento TimeSelected possui as propriedades NewTime e OldTime, que especificam o horário novo e o antigo, respectivamente.

WebView

WebView adiciona um evento ProcessTerminated que é gerado quando um processo WebView termina inesperadamente. O objeto WebViewProcessTerminatedEventArgs que acompanha esse evento define propriedades específicas da plataforma que indicam por que o processo falhou.

Associações compiladas no código

As associações escritas em código normalmente usam caminhos de cadeia de caracteres que são resolvidos em runtime com reflexão, e a sobrecarga de fazer isso varia de plataforma para plataforma. O .NET MAUI 9 apresenta um método de extensão adicional SetBinding que define associações usando um argumento Func em vez de um caminho de cadeia de caracteres:

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

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

Essa abordagem de associações compiladas oferece os seguintes benefícios:

  • Associações compiladas melhoram o desempenho resolvendo expressões de associação em tempo de compilação, em vez de runtime.
  • Uma melhor experiência de solução de problemas para o desenvolvedor porque associações inválidas são relatadas como erros de build.
  • IntelliSense durante a edição.

Nem todos os métodos podem ser usados para definir uma associação compilada. A expressão deve ser uma expressão de acesso de propriedade simples. Os exemplos a seguir mostram expressões de associação válidas e invá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}";

Além disso, o .NET MAUI 9 adiciona um método Binding.Create que define a associação diretamente no objeto com um Func, e retorna a instância do objeto de associação:

// 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

As associações compiladas são necessárias em vez de associações baseadas em cadeia de caracteres em aplicativos NativeAOT e em aplicativos com corte completo habilitado.

Associações compiladas em XAML

No .NET MAUI 8, as associações compiladas são desabilitadas para qualquer expressão de associação XAML que define a propriedade Source e não têm suporte em várias associações. Essas restrições foram removidas no .NET MAUI 9. Para obter informações sobre como compilar expressões de associação XAML que definem a Source propriedade, consulte Compilar associações que definem a Source propriedade.

Por padrão, o .NET MAUI 9 produz avisos de build para associações que não usam associações compiladas. Para obter mais informações sobre avisos de associações compiladas XAML, consulte Avisos de associações compiladas XAML.

Desconexão do manipulador

Ao implementar um controle personalizado usando manipuladores, toda implementação de manipulador de plataforma deve implementar o método DisconnectHandler(), para executar qualquer limpeza de exibição nativa, como cancelar a assinatura de eventos. No entanto, antes do .NET MAUI 9, a implementação DisconnectHandler() não é intencionalmente invocada pelo .NET MAUI. Em vez disso, você teria que invocá-lo por conta própria ao optar por limpar um controle, como ao navegar para trás em um aplicativo.

No .NET MAUI 9, os manipuladores se desconectam automaticamente de seus controles quando possível, como ao navegar para trás em um aplicativo. Em alguns cenários, talvez você não queira esse comportamento. Portanto, o .NET MAUI 9 adiciona uma propriedade anexada HandlerProperties.DisconnectPolicy para controlar quando os manipuladores são desconectados de seus controles. Essa propriedade requer um HandlerDisconnectPolicy argumento, com a enumeração definindo os seguintes valores:

  • Automatic, o que indica que os manipuladores serão desconectados automaticamente. Esse é o valor padrão da propriedade anexada HandlerProperties.DisconnectPolicy.
  • Manual, o que indica que os manipuladores terão que ser desconectados manualmente invocando a implementação DisconnectHandler().

O exemplo a seguir mostra a configuração da propriedade anexada HandlerProperties.DisconnectPolicy:

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

Este é o código C# equivalente:

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

Além disso, há um método de extensão DisconnectHandlers que desconecta os manipuladores de um determinado IView:

video.DisconnectHandlers();

Ao se desconectar, o método DisconnectHandlers se propagará para baixo na árvore de controle até que seja concluído ou chegue a um controle que tenha definido uma política manual.

Suporte a várias janelas

O .NET MAUI 9 adiciona a capacidade de trazer uma janela específica para a frente no Mac Catalyst e no Windows com o método Application.Current.ActivateWindow:

Application.Current?.ActivateWindow(windowToActivate);

Implantação do AOT nativo

No .NET MAUI 9, você pode optar pela implantação do AOT nativo no iOS e no Mac Catalyst. A implantação nativa do AOT produz um aplicativo .NET MAUI que foi compilado antecipadamente (AOT) para código nativo. Isso produz os seguintes benefícios:

  • Tamanho reduzido do pacote do aplicativo, normalmente até 2,5 vezes menor.
  • Tempo de inicialização mais rápido, normalmente até 2x mais rápido.
  • Tempo de construção mais rápido.

Para obter mais informações, consulte Implantação de AOT nativa no iOS e no Mac Catalyst.

Incorporação nativa

O .NET MAUI 9 inclui APIs completas para cenários de inserção nativos, que anteriormente precisavam ser adicionados manualmente ao seu projeto:

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, você pode usar o método ToPlatformEmbedded, passando o Window para a plataforma na qual o aplicativo está sendo executado:

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

Em ambos os exemplos, nativeView é uma versão específica da plataforma do mauiView.

Para inicializar um aplicativo inserido nativo no .NET MAUI 9, chame o método de extensão UseMauiEmbeddedApp em seu objeto MauiAppBuilder:

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

        builder
            .UseMauiEmbeddedApp<App>();

        return builder.Build();
    }
}

Para obter mais informações, consulte Inserção nativa.

Modelos de projeto

O .NET MAUI 9 adiciona um modelo de projeto .NET MAUI Blazor Hybrid e Aplicativo Web ao Visual Studio, que cria uma solução com um aplicativo .NET MAUI Blazor Hybrid com um aplicativo Web Blazor, os quais compartilham código comum em um projeto de biblioteca de classes Razor.

O modelo também pode ser usado de dotnew new:

dotnet new maui-blazor-web -n AllTheTargets

Dicionários de recurso

No .NET MAUI 9, o XAML de um ResourceDictionary XAML autônomo (que não é respaldado por um arquivo code-behind) é compilado por padrão. Para recusar esse comportamento, especifique <?xaml-comp compile="false" ?> após o cabeçalho XML.

Filtragem

O corte completo agora é suportado pela configuração da $(TrimMode) propriedade MSBuild como full. Para obter mais informações, consulte Cortar um aplicativo .NET MAUI.

Cortando incompatibilidades

Os seguintes recursos do .NET MAUI são incompatíveis com o corte completo e serão removidos pelo aparador:

Opções de recursos de corte

O .NET MAUI tem diretivas de corte, conhecidas como opções de recursos, que possibilitam preservar o código para recursos que não são seguros para corte. Essas diretivas trimmer podem ser usadas quando a $(TrimMode) propriedade build é definida como full, bem como para NativeAOT:

Propriedade do MSBuild Descrição
MauiEnableVisualAssemblyScanning Quando definido como true, o .NET MAUI examinará assemblies em busca de tipos que implementam IVisual e atributos [assembly:Visual(...)] e os registrará. Por padrão, essa propriedade de build é definida como false.
MauiShellSearchResultsRendererDisplayMemberNameSupported Quando definido como false, o valor de SearchHandler.DisplayMemberName será ignorado. Em vez disso, você deve fornecer um ItemTemplate para definir a aparência dos resultados SearchHandler. Por padrão, essa propriedade de build é definida como true.
MauiQueryPropertyAttributeSupport Quando definidos como false, os atributos [QueryProperty(...)] não serão usados para definir valores de propriedade durante a navegação. Em vez disso, você deve implementar a interface IQueryAttributable para aceitar parâmetros de consulta. Por padrão, essa propriedade de build é definida como true.
MauiImplicitCastOperatorsUsageViaReflectionSupport Quando definido como false, o .NET MAUI não procurará operadores de conversão implícitos ao converter valores de um tipo para outro. Isso pode afetar associações entre propriedades com tipos diferentes e definir o valor de propriedade de um objeto associável com um valor de um tipo diferente. Em vez disso, você deve definir um TypeConverter para o tipo e anexá-lo ao tipo usando o atributo TypeConverterAttribute. Por padrão, essa propriedade de build é definida como true.
_MauiBindingInterceptorsSupport Quando definido como false, o .NET MAUI não interceptará nenhuma chamada para os métodos SetBinding e não tentará compilá-los. Por padrão, essa propriedade de build é definida como true.
MauiEnableXamlCBindingWithSourceCompilation Quando definido como true, o .NET MAUI compilará todas as associações, incluindo aquelas em que a Source propriedade é usada. Se você habilitar esse recurso, certifique-se de que todas as associações tenham o correto x:DataType para que sejam compiladas ou limpe o tipo de dados com x:Data={x:Null}} se a associação não deve ser compilada. Por padrão, essa propriedade de build só é definida como quando o true corte completo ou a implantação AOT nativa está habilitada.

Essas propriedades do MSBuild também têm opções equivalentes AppContext :

  • A MauiEnableVisualAssemblyScanning propriedade MSBuild tem uma opção equivalente AppContext chamada Microsoft.Maui.RuntimeFeature.IsIVisualAssemblyScanningEnabled.
  • A MauiShellSearchResultsRendererDisplayMemberNameSupported propriedade MSBuild tem uma opção equivalente AppContext chamada Microsoft.Maui.RuntimeFeature.IsShellSearchResultsRendererDisplayMemberNameSupported.
  • A MauiQueryPropertyAttributeSupport propriedade MSBuild tem uma opção equivalente AppContext chamada Microsoft.Maui.RuntimeFeature.IsQueryPropertyAttributeSupported.
  • A MauiImplicitCastOperatorsUsageViaReflectionSupport propriedade MSBuild tem uma opção equivalente AppContext chamada Microsoft.Maui.RuntimeFeature.IsImplicitCastOperatorsUsageViaReflectionSupported.
  • A _MauiBindingInterceptorsSupport propriedade MSBuild tem uma opção equivalente AppContext chamada Microsoft.Maui.RuntimeFeature.AreBindingInterceptorsSupported.
  • A MauiEnableXamlCBindingWithSourceCompilation propriedade MSBuild tem uma opção equivalente AppContext chamada Microsoft.Maui.RuntimeFeature.MauiEnableXamlCBindingWithSourceCompilationEnabled.

A maneira mais fácil de consumir uma opção de recurso é colocar a propriedade MSBuild correspondente no arquivo de projeto do aplicativo (*.csproj), o que faz com que o código relacionado seja cortado dos assemblies MAUI do .NET.

Compilador XAML

No .NET MAUI 9, os códigos de erro do compilador XAML alteraram seu prefixo de XFC para XC. Certifique-se de atualizar as $(WarningsAsErrors)propriedades , $(WarningsNotAsErrors)e $(NoWarn) build nos arquivos de projeto do aplicativo, se usados, para fazer referência ao novo prefixo.

Extensões de marcação XAML

Todas as classes que implementam IMarkupExtension, IMarkupExtension<T>, IValueProvider e IExtendedTypeConverter precisam ser anotadas com o RequireServiceAttribute ou AcceptEmptyServiceProviderAttribute. Isso é necessário devido a uma otimização do compilador XAML introduzida no .NET MAUI 9 que permite a geração de código mais eficiente, o que ajuda a reduzir o tamanho do aplicativo e melhorar o desempenho do runtime.

Para informações sobre como anotar extensões de marcação com esses atributos, consulte Provedores de serviços.

Sincronização do Xcode

O .NET MAUI 9 inclui a sincronização do Xcode (xcsync), que é uma ferramenta que permite usar o Xcode para gerenciar arquivos específicos da Apple com projetos .NET, incluindo catálogos de ativos, arquivos plist, storyboards e arquivos xib. A ferramenta tem dois comandos principais para gerar um projeto Xcode temporário a partir de um projeto .NET e sincronizar as alterações dos arquivos Xcode de volta para seu projeto .NET.

Use dotnet build com os comandos xcsync-generate ou xcsync-sync para gerar ou sincronizar esses arquivos e passar um arquivo de projeto e argumentos adicionais:

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

Para mais informações, consulte Sincronização Xcode.

APIs obsoletas

O .NET MAUI 9 substitui algumas APIs, que serão completamente removidas em uma versão futura.

Frame

O controle Frame está marcado como obsoleto no .NET MAUI 9 e será completamente removido em uma versão futura. O controle Border deve ser usado em seu lugar. Para obter mais informações, confira Borda.

MainPage

Em vez de definir a primeira página do seu aplicativo usando a propriedade MainPage em um objeto Application, você deve definir a propriedade Page em um Window para a primeira página do seu aplicativo. Isso é o que acontece internamente no .NET MAUI quando você define a propriedade MainPage, portanto, não há nenhuma alteração de comportamento introduzida pela propriedade MainPage que está sendo marcada como obsoleta.

O exemplo a seguir demonstra a configuração da propriedade Page em um Window através da substituição de CreateWindow:

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

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

A propriedade MainPage é mantida para o .NET MAUI 9, mas será completamente removida em uma versão futura.

Layouts de compatibilidade

As classes de layout de compatibilidade no namespace Microsoft.Maui.Controls.Compatibility ficaram obsoletas.

Chamadas de medida herdadas

Os seguintes VisualElement métodos de medida tornaram-se obsoletos:

Esses são métodos de medida herdados que não funcionam corretamente com as expectativas de layout do .NET MAUI.

Como substituto, o VisualElement.Measure(Double, Double) método foi introduzido. Este método retorna o tamanho mínimo que um elemento visual precisa ter para ser exibido no dispositivo. As margens são excluídas da medida, mas são devolvidas com o tamanho. Esse é o método preferencial a ser chamado ao medir uma exibição.

Além disso, o struct SizeRequest está obsoleto. Em vez disso, Size deve ser usado.

.NET para Android

O .NET para Android no .NET 9, que adiciona suporte para a API 35, inclui trabalho para reduzir os tempos de build e melhorar a capacidade de corte dos aplicativos para reduzir o tamanho e melhorar o desempenho. Para obter mais informações sobre o .NET para Android no .NET 9, consulte as seguintes notas de versão:

Pacotes de ativos

O .NET para Android no .NET 9 apresenta a capacidade de colocar ativos em um pacote separado, conhecido como pacote de ativos. Isso permite que você carregue jogos e aplicativos que normalmente seriam maiores do que o tamanho do pacote básico permitido pelo Google Play. Ao colocar esses ativos em um pacote separado, você obtém a capacidade de carregar um pacote com até 2 GB de tamanho, em vez do tamanho do pacote básico de 200 MB.

Importante

Os pacotes de ativos só podem conter ativos. No caso do .NET para Android, isso significa itens que têm a ação de build AndroidAsset.

Os aplicativos do .NET MAUI definem os ativos por meio da ação de build MauiAsset. Um pacote de ativos pode ser especificado por meio do atributo AssetPack:

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

Observação

Os metadados adicionais serão ignorados por outras plataformas.

Se tiver itens específicos que quiser colocar em um pacote de ativos, você poderá usar o atributo Update para definir os metadados do AssetPack:

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

Os pacotes de ativos podem ter opções de entrega diferentes, que controlam quando seus ativos serão instalados no dispositivo:

  • Os pacotes install-time são instalados ao mesmo tempo que o aplicativo. Esse tipo de pacote pode ter até 1 GB de tamanho, mas você só pode ter um deles. Esse tipo de entrega é especificado com metadados InstallTime.
  • Os pacotes de acompanhamento rápido serão instalados em algum momento, logo após a instalação do aplicativo ter sido finalizada. O aplicativo poderá ser iniciado enquanto esse tipo de pacote estiver sendo instalado, de modo que você deverá verificar se acabou de ser instalado antes de tentar usar os ativos. Esse tipo de pacote de ativos pode ter até 512 MB de tamanho. Esse tipo de entrega é especificado com metadados FastFollow.
  • Os pacotes sob demanda nunca serão baixados para o dispositivo, a menos que o aplicativo solicite isso especificamente. O tamanho total de todos os seus pacotes de ativos não pode exceder 2 GB e você pode ter até 50 pacotes de ativos separados. Esse tipo de entrega é especificado com metadados OnDemand.

Nos aplicativos do .NET MAUI, o tipo de entrega pode ser especificado com o atributo DeliveryType em um MauiAsset:

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

Para obter mais informações sobre pacotes de ativos do Android, confira Pacotes de ativos do Android.

Suporte para Android 15

O .NET para Android no .NET 9 adiciona associações do .NET para o Android 15 (API 35). Para criar para essas APIs, atualize a estrutura de destino do seu projeto para net9.0-android:

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

Observação

Você também pode especificar net9.0-android35 como uma estrutura de destino, mas o número 35 provavelmente será alterado em versões futuras do .NET para corresponder às versões mais recentes do sistema operacional Android.

Arquiteturas de 64 bits por padrão

O .NET para Android no .NET 9 não cria mais os seguintes RIDs (identificadores de runtime) por padrão:

  • android-arm
  • android-x86

Isso deve melhorar os tempos de compilação e reduzir o tamanho dos arquivos do Android .apk . O Google Play é compatível com a divisão de pacotes de apps por arquitetura.

Se você precisar compilar para essas arquiteturas, poderá adicioná-las ao arquivo de projeto (.csproj):

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

Ou em um projeto multidirecionado:

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

Métodos de marshal do Android

Melhorias nos métodos de marshal do Android no .NET 9 fizeram com que o recurso funcionasse de forma mais confiável em aplicativos, mas ainda não é o padrão. A ativação desse recurso resultou em uma melhoria de ~10% no desempenho em um aplicativo de teste.

Os métodos de marshal do Android podem ser ativados em seu arquivo de projeto (.csproj) por meio da $(AndroidEnableMarshalMethods) propriedade:

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

Para obter detalhes específicos sobre o recurso, consulte a documentação ou implementação do recurso no GitHub.

Aprimoramentos de redução

No .NET 9, os assemblies de API do Android (Mono.Android.dll, Java.Interop.dll) agora são totalmente compatíveis com cortes. Para aceitar o corte completo, defina a $(TrimMode) propriedade no arquivo de projeto (.csproj):

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

Isso também permite cortar analisadores, para que os avisos sejam introduzidos para qualquer código C# problemático.

Para obter mais informações, consulte Granularidade de corte.

.NET para iOS

O .NET 9 no iOS, tvOS, Mac Catalyst e macOS usa o Xcode 16.0 para as seguintes versões de plataforma:

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

Para obter mais informações sobre o .NET 9 no iOS, tvOS, Mac Catalyst e macOS, confira as seguintes notas de versão:

Associações

O .NET para iOS 9 introduz a capacidade de ter vários destinos de versão do .NET para associações do iOS. Por exemplo, talvez seja necessário criar um projeto de biblioteca para duas versões distintas do iOS:

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

Isso produzirá duas bibliotecas, uma usando vinculações do iOS 17.0 e outra usando vinculações do iOS 17.2.

Importante

Um projeto de aplicativo sempre deve ter como destino o SDK do iOS mais recente.

Aprimoramentos de redução

No .NET 9, os assemblies iOS e Mac Catalyst (Microsoft.iOS.dll, Microsoft.MacCatalyst.dll etc.) agora são totalmente compatíveis com cortes. Para aceitar o corte completo, defina a $(TrimMode) propriedade no arquivo de projeto (.csproj):

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

Isso também permite cortar analisadores, para que os avisos sejam introduzidos para qualquer código C# problemático.

Para obter mais informações, consulte Granularidade de corte.

AOT nativo para iOS &Mac Catalyst

No .NET para iOS 9, a compilação Ahead Of Time (AOT) nativa para iOS e Mac Catalyst aproveita o corte completo para reduzir o tamanho do pacote e o desempenho de inicialização do aplicativo. O NativeAOT se baseia no corte completo, também optando por um novo runtime.

Importante

Seu aplicativo e suas dependências devem ser totalmente ajustáveis para utilizar esse recurso.

O NativeAOT requer que os aplicativos sejam criados com zero avisos de aparador, a fim de provar que o aplicativo funcionará corretamente em tempo de execução.

Confira também