Partilhar via


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);

Por padrão, BlazorWebView agora dispara e esquece o descarte assíncrono do WebViewManager. Isso reduz o potencial de deadlocks de descarte no Android.

Aviso

Esse comportamento padrão de disparar e esquecer significa que o descarte pode retornar antes que todos os objetos sejam descartados, o que pode causar alterações comportamentais em seu aplicativo. Os itens descartados são parcialmente os próprios tipos internos do Blazor, mas também tipos definidos pelo aplicativo, como serviços com escopo usados na parte BlazorWebView do aplicativo.

Para recusar esse comportamento, você deve configurar seu aplicativo para bloquear ao descartar por meio de uma AppContext opção no CreateMauiApp método em sua MauiProgram classe:

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

Se o aplicativo estiver configurado para bloquear no descarte por meio dessa opção, BlazorWebView o executará o descarte assíncrono sobre sincronização, o que significa que ele bloqueará o thread até que o descarte assíncrono seja concluído. No entanto, isso pode causar deadlocks se o descarte precisar executar código no mesmo thread (porque o thread é bloqueado durante a espera).

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 BindingBase.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.

Injeção de dependência

Em um aplicativo Shell, você não precisa mais registrar suas páginas com o contêiner de injeção de dependência, a menos que queira influenciar o tempo de vida da página em relação ao contêiner com os AddSingletonmétodos , AddTransient, or AddScoped . Para obter mais informações sobre esses métodos, consulte Tempo de vida da dependência.

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 modelo de projeto do aplicativo .NET MAUI inclui a capacidade de criar um aplicativo de tarefas pendentes totalmente funcional, usando controles do Syncfusion Toolkit for .NET MAUI para visualizar dados e mantê-los em um banco de dados local baseado em SQLite. Para criar esse aplicativo de tarefas pendentes, crie um novo projeto no Visual Studio usando o modelo de projeto do Aplicativo .NET MAUI e marque a caixa de seleção Incluir conteúdo de exemplo na janela Informações adicionais:

Captura de tela de como adicionar páginas de exemplo do SyncFusion ao seu projeto de aplicativo .NET MAUI.

O aplicativo de tarefas pendentes também pode ser criado a partir da CLI do .NET com a --sample-content opção ou -sc :

dotnet new maui --sample-content -n MyProject

O .NET MAUI 9 também adiciona um modelo de projeto .NET MAUI Blazor Hybrid e Web App ao Visual Studio que cria uma solução com um aplicativo .NET MAUI Blazor Hybrid com um aplicativo Web Blazor, que compartilha código comum em um projeto de biblioteca de classes Razor.

O modelo também pode ser usado na CLI do .NET:

dotnet new maui-blazor-web -n MyProject

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 AOT nativo:

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 quando o false corte completo está habilitado.
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 quando o false corte completo ou AOT nativo está habilitado.
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 quando o false corte completo ou AOT nativo está habilitado.
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 quando o false corte completo ou AOT nativo está habilitado.
_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 é definida como quando o true corte completo ou AOT nativo está habilitado.
MauiHybridWebViewSupported Quando definido como false, o HybridWebView controle não estará disponível. Por padrão, essa propriedade de build é definida como quando o false corte completo ou AOT nativo está habilitado.

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 MauiHybridWebViewSupported propriedade MSBuild tem uma opção equivalente AppContext chamada Microsoft.Maui.RuntimeFeature.IsHybridWebViewSupported.

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.

Implantação de aplicativos do Windows

Ao depurar e implantar um novo projeto .NET MAUI no Windows, o comportamento padrão no .NET MAUI 9 é implantar um aplicativo não empacotado. Para obter mais informações, confira Implantar e depurar seu aplicativo .NET MAUI no Windows.

Códigos de erro do 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());
    }
}

O código que acessa a Application.Current.MainPage propriedade agora deve acessar a Application.Current.Windows[0].Page propriedade para aplicativos com uma única janela. Para aplicativos com várias janelas, use a Application.Current.Windows coleção para identificar a janela correta e acesse a Page propriedade. Além disso, cada elemento apresenta uma Window propriedade, que pode ser acessada quando o elemento faz parte da janela atual, a partir da qual a Page propriedade pode ser acessada (Window.Page). O código da plataforma pode recuperar o objeto do IWindow aplicativo com o Microsoft.Maui.Platform.GetWindow método de extensão.

Embora a MainPage propriedade seja mantida no .NET MAUI 9, ela 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.

Atualizar do .NET 8 para o .NET 9

Para atualizar seus projetos do .NET MAUI do .NET 8 para o .NET 9, primeiro instale o .NET 9 e a carga de trabalho do .NET MAUI com o Visual Studio 17.12+, ou com o Visual Studio Code e a extensão .NET MAUI e o .NET e as cargas de trabalho do .NET MAUI, ou com o instalador autônomo e o dotnet workload install maui comando.

Atualizar arquivo de projeto

Para atualizar seu aplicativo .NET MAUI do .NET 8 para o .NET 9, abra o arquivo de projeto do aplicativo (.csproj) e altere os TFMs (Monikers da Estrutura de Destino) de 8 para 9. Se você estiver usando um TFM, como net8.0-ios15.2, não se esqueça de corresponder à versão da plataforma ou removê-la completamente. O exemplo a seguir mostra os TFMs para um projeto do .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>

O exemplo a seguir mostra os TFMs para um projeto .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>

Se o arquivo de projeto do aplicativo fizer referência a uma versão do .NET 8 do Microsoft.Maui.Controls pacote NuGet, diretamente ou por meio da $(MauiVersion) propriedade build, atualize-o para uma versão do .NET 9. Em seguida, remova a referência de pacote para o Microsoft.Maui.Controls.Compatibility pacote NuGet, desde que seu aplicativo não use nenhum tipo desse pacote. Além disso, atualize a referência de pacote do Microsoft.Extensions.Logging.Debug pacote NuGet para a versão mais recente do .NET 9.

Se o seu aplicativo for direcionado ao iOS ou Mac Catalyst, atualize as propriedades de $(SupportedOSPlatformVersion) compilação dessas plataformas para 15.0:

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

Ao depurar e implantar um novo projeto .NET MAUI no Windows, o comportamento padrão no .NET 9 é implantar um aplicativo não empacotado. Para adotar esse comportamento, consulte Converter um aplicativo .NET MAUI do Windows empacotado em não empacotado.

Antes de criar o seu aplicativo atualizado pela primeira vez, exclua as pastas bin e obj. Quaisquer erros de compilação e avisos irão guiá-lo para as próximas etapas.

Atualizar códigos de erro do compilador XAML

Os códigos de erro do compilador XAML foram alterados de prefixo de XFC para XC, portanto, atualize as $(WarningsAsErrors)propriedades , $(WarningsNotAsErrors)e $(NoWarn) build no arquivo de projeto do aplicativo, se usado, para fazer referência ao novo prefixo.

Endereçar novos avisos do compilador XAML para associações compiladas

Avisos de build serão produzidos para associações que não usam associações compiladas e precisarão ser resolvidos. Para obter mais informações, consulte Avisos de associações compiladas XAML.

Atualizar extensões de marcação XAML

As extensões de marcação XAML precisarão ser anotadas com o RequireServiceAttribute ou AcceptEmptyServiceProviderAttribute. Isso é necessário devido a uma otimização do compilador XAML 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 obter mais informações, consulte Provedores de serviços.

Endereçar APIs preteridas

O .NET MAUI 9 substitui algumas APIs, que serão completamente removidas em uma versão futura. Portanto, aborde todos os avisos de build sobre APIs preteridas. Para obter mais informações, consulte APIs preteridas.

Adotar associações compiladas que definem a propriedade Source

Você pode optar por compilar associações que definem a Source propriedade, para aproveitar o melhor desempenho do tempo de execução. Para obter mais informações, consulte Compilar associações que definem a Source propriedade.

Adotar associações compiladas em C#

Você pode optar por compilar expressões de associação declaradas no código, para aproveitar o melhor desempenho do tempo de execução. Para obter mais informações, consulte Associações compiladas no código.

Adote o corte completo

Você pode adotar o uso do corte completo, para reduzir o tamanho geral do seu aplicativo, definindo a $(TrimMode) propriedade MSBuild como full. Para obter mais informações, consulte Cortar um aplicativo .NET MAUI.

Adote a implantação do NativeAOT em plataformas com suporte

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. Para obter mais informações, consulte Implantação de AOT nativa no iOS e no Mac Catalyst.

.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