MAUI - Por onde começar? Parte 1: Entendendo o MAUI
Tags: maui, dotnet, android, ios
Published: 2024-03-31 17:01:33

Olá amigos, hoje é um dia especial para alguém que _**do nada**_ resolveu aprender **MAUI (.NET Multi-platform App UI)**, se esse é você, então, vem comigo porque eu bolei essa série de artigos que tentarão sanar as dúvidas que mais recebo da comunidade em grupos do telegram que participo, e também, não menos importante, fiz um tutorial com as principais bibliotecas que você deve ter no seu projeto, estrategias de organização de projeto, uso da arquitetura MVVM, Injeção de dependência e muito mais. Prometo ser o mais objetivo possivel nesse post em sanar tais duvidas. Então vamos lá:

----

## O que é MAUI e qual a sua diferença para o WPF, UWP e Windows Forms?

Para início de conversa, entenderemos que **MAUI (.NET Multi-platform App UI)** é uma estrutura multiplataforma [open source](https://github.com/dotnet/maui) para criar aplicativos moveis usando uma mesma base de código compartilhada, essa estrutura vai te permitir publicar aplicativos para **Android**, **IOS**, **Windows **e **MacOS**. O MAUI é uma evolução do [Xamarin](https://github.com/xamarin/) que também tem esse mesmo proposito, porem com uma outra arquitetura menos extensiva, dado que nos obriga quase sempre a mudar de projetos para efetuar mudanças de acordo com a plataforma, por exemplo. 

O Principio de criação de interface no MAUI usa principalmente O XAML e C#, o que se assemelha com outras tecnologias para desenvolvimento para Windows desktop como o **WPF (Windows Presentation Foundation)** e **UWP (Universal Windows Platform)**. A maior diferença entre essas tecnologias são os propositos delas. Enquanto no WPF a gente somente cria aplicativos para Windows Desktop, ele não é multiplataforma, porém te permite acessar as interface do sistema operacional ao contrario do UWP.

O **UWP (Universal Windows Platform)** é um tipo de arquitetura para desenvolvimento desktop com o diferencial que lhe permite usar a mesma base de código para publicação em outras versões do windows para PC, Tablets, XBOX e Hololens, antigamente era também usado para criação de apps para o finado _Windows Phone_. Nele também usamos XAML e C# para criação de interfaces, mas ao contrario do WPF, os apps que rodam nessa tecnologia estarão sendo executados dentro de uma sandbox, e para ter acesso a recursos do sistema operacional, é preciso pedir permissão ao Usuário, semelhante ao que acontece com Android e IOS.

Vamos falar um pouco do **Windows Forms**, uma tecnologia antiga, porém viva, e com muitos devs desempenhados em manter assim, é uma tecnologia que foi predecessora do WPF, seu diferencial é que te permite ~~sofrer enquanto estar à~~ criar aplicativos para windows usando o que chamados de WYSIWYG _(what you see is what you get)_ e também adicionando controles em tempo de execução, e seus componentes são compativeis com o WPF e vice-versa, ele executa da mesma forma do WPF, e também te permite acessar interfaces do sistema operacional sem pedir permissão como o UWP, porém não é multiplataforma, como também você não tem um XML charmoso onde você pode controlar os controles na interface, restringindo sua interação a clicar e arrastar controles e adicionar eventos para executar comandos.

Então, resumindo:
- WPF (Windows Presentation Foundation):
 - É uma tecnologia para criar aplicativos de desktop no Windows.
 - Usa XAML para definir a interface do usuário.
 - Foi projetado principalmente para Windows.
 - Não é multiplataforma.
- UWP (Universal Windows Platform):
 - Também é para aplicativos de desktop no Windows.
 - Usa XAML e C#.
 - Foi projetado para ser executado em várias versões do Windows.
 - Suporta dispositivos como PCs, tablets, Xbox e HoloLens.
- Windows Forms:
 - É uma tecnologia mais antiga para criar aplicativos de desktop no Windows.
 - Usa C# e uma abordagem baseada em eventos.
 - Não é multiplataforma.
- .NET MAUI:
 - Unifica as APIs do Android, iOS, macOS e Windows em uma única API.
 - Permite compartilhar código, testes e lógica de negócios entre plataformas.
 - Oferece controles de interface do usuário recriados do zero para melhor desempenho.
 - É a escolha ideal para desenvolvedores que desejam criar aplicativos multiplataforma com uma única base de código.

---- 

## Vamos ao que interessa, seu primeiro App MAUI!

Ufa, depois dessa longa explicação, agora vamos entender por onde começar. Estarei usando o sistema operacional Windows com o [Visual Studio Community 2022](https://visualstudio.microsoft.com/vs/community/) para fazer nosso app, nada impede você se usar o [VSCode](https://code.visualstudio.com/Download).

Então vamos explorar o template inicial que a Microsoft nos fornece  ao criar nosso primeiro app. 

- Vamos começar criando um novo projeto no visual studio e selecionando o tipo de projeto MAUI como na imagem abaixo: 

![Selecionando o tipo de projeto .net MAUI](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vxrxdwwzrbnl1g3jbtkj.png)

- Agora vamos dar um nome para ele, vou chamar de "MeuPrimeiroAppMAUI"


![Dando o nome para o projeto](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s9ti25j2w6potdsj59nc.png)

e voilá, agora temos o nosso projeto aqui, mas o que nós estamos vendo?

![Primeira estrutura de pasta](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/is7aicivfh1oq4745sg6.png)

----

### Entendendo a estrutura padrão de pastas no MAUI

Em geral, como estamos usando .NET, você verá os mesmos elementos de outros tipos de apps do framework, como a sessão de "dependencies" e "properties", mas no MAUI tem umas coisinhas interessantes, deixa eu explicar:

- **Dependencias(Dependencies)**

Essa sessão é onde você pode configurar que dependencias seu projeto tem, seja NuGet Packages, outros Projetos e até mesmo Dlls; bom, nada novo até aqui. Porém, no MAUI você vai ver outros tipos de dependencias como _net8.0-android_, _net8.0-ios_ e etc. Mas o que são isso? Em resposta curta, isso determina que exitem dependencias exclusivas para serem publicadas por plataforma, em outra palavras, quando você estiver desenvolvendo para Android, o MAUi vai olhar para as dependencias listadas em _net8.0-android_, enquanto para iOS, ele olhará para .net8.0-ios, e assim por diante.
Pô legal, né?! Mas onde isso é configurado?

Se você usar o botão direito do mouse em cima do projeto e clicar em "Editar arquivo de projeto" (edit project file), voce verá que os tipos de projetos estarão listados bem no inicio em **TargetFrameworks**

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

Você deve ter notado que a estrutura desses target frameworks é sempre (versão do framework)-(plataforma), podendo ser net9.0-android, net6.0-ios, então com isso em mente vamos seguindo.

---- 

- **Pasta "Platforms"**

Essa pasta é onde estarão nossos arquivos especificos por plataforma, você deve ver uma pasta "Android", "iOS", "MacCatalyst" , "Tizen" e "Windows". Qualquer classe colocada nesses diretorios, só estarão disponiveis na plataforma correspondente. Então todas as outras pastas que você criar, ou arquivo que estiver fora, será automaticamente interpretado como multiplataforma.

----

- **Pasta "Resources"**

Essa pasta em geral deixa as pessoas com muitas dúvidas de onde pode colocar imagens, arquivos extras, e alguns devs colocam arquivos em locais que não são apropriados por desconhecer a funcão dessa pasta, então deixa eu desmistificar de acordo com sua intenção: 
 - Para imagens deve ser colocadas dentro da pasta "Images", preferencialmente use _arquivos svg_, mas pode ser qualquer tipo.
 - Para icone do app, aqueles que o usuário verá na área de trabalho, use a pasta "AppIcon", de preferencia _arquivos svg_ também.
 - Para novas fontes, use a pasta "Fonts", nela você pode baixar fontes da internet e colocar nessa pasta e já sair usando ao redor do seu app.
 - A pasta "raw" é de longe a que mais sofre de mal uso, então vou desmistificar agora, qualquer arquivo extra, sendo um json, xml, ou  até mesmo qualquer tipo de arquivo, você pode colocar nessa pasta, cada plataforma exige uma API especifica para acessa-la, mas é muito fácil configurar isso.
 - A pasta "Splash" é onde colocamos nossas splash screen. SplashScreen é a primeira pagina que o sistema operacional invoca quando chama o seu app para a execução em primeiro plano.
 - a pasta "Styles" é onde podemos colocar nossas folhas de estilo compartilhadas, semelhante ao **CSS**, mas tudo aqui é **XAML**, vou me aprofundar nisso nos próximos artigos. Você deve perceber que temos um arquivo de cores (Colors.xaml) e um arquivo de estilos.

Todos as pastas acima serão compiladas de diferentes maneiras, mas a RAW ela não é compilada, ela será colocada de forma "bruta" nas pastas equivalentes por plataforma.

---- 

- **App.xaml e App.xaml.cs (desmistificando de uma vez por todas)**

Apartir de agoras, você verá um comportamento comum quando você criar novos arquivos xaml no seu projeto, eles sempre virão com um arquivo xaml.cs. Só pra desmistificar a grosso modo essa parte para que você entenda, os arquivos XAML são representacões em XML de código C#, então quando criamos um arquivo XAML devemos entender que basicamente estamos escrevendo código C# de outra maneira, com XML. Dúvida de mim? Então vamos a arquivo do App.xaml

```xml
<?xml version = "1.0" encoding = "UTF-8" ?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MeuPrimeiroAppMAUI"
             x:Class="MeuPrimeiroAppMAUI.App">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources/Styles/Colors.xaml" />
                <ResourceDictionary Source="Resources/Styles/Styles.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>
```
observe essas linhas 

```
             xmlns:local="clr-namespace:MeuPrimeiroAppMAUI"
             x:Class="MeuPrimeiroAppMAUI.App"
```

e observe o código C# na App.xaml.cs

```cs
  public partial class App : Application
  {
      public App()
      {
          InitializeComponent();

          MainPage = new AppShell();
      }
  }
```
 
você deve reparar a palavra-chave "partial" nessa declaração da classe `public partial class App : Application`, como também a classe sendo associada ao documento XAML em `x:Class="MeuPrimeiroAppMAUI.App`. Usamos _Partial _em _C#_ quando queremos separar uma classe em duas ou mais documentos sem que isso afete o comportamento dela para compilador. Então, se nosso XAML é uma partial de nossa classe App (que também é uma partial) os dois documentos são representação da mesma classe.

----

- **Para que serve a classe App?**

A classe App no .NET MAUI desempenha um papel fundamental na criação de aplicativos multiplataforma. Vamos explorar o que ela faz:

 - Definição do Aplicativo:
A classe App é o ponto de entrada para o seu aplicativo .NET MAUI. Ela é responsável por inicializar e configurar o aplicativo.
  - Quando você inicia o aplicativo, o método OnStartup da classe App é chamado. É aqui que você pode configurar serviços, definir a página inicial e realizar outras tarefas de inicialização.
 - Gerenciamento do Ciclo de Vida:
  - A classe App também gerencia o ciclo de vida do aplicativo. Ela responde a eventos como **OnStart**, **OnSleep **e **OnResume**.
  - **OnStart**: Chamado quando o aplicativo é iniciado. Aqui, você pode configurar recursos iniciais e preparar o aplicativo para uso.
  - **OnSleep**: Chamado quando o aplicativo entra em segundo plano (por exemplo, quando o usuário muda para outro aplicativo). Você pode salvar o estado do aplicativo aqui.
  - **OnResume**: Chamado quando o aplicativo volta ao primeiro plano. Use isso para restaurar o estado do aplicativo.
 - Configuração de Páginas e Navegação:
  - A classe App define a página inicial do aplicativo usando o método MainPage. Você pode atribuir uma instância de uma página (como ContentPage ou NavigationPage) a essa propriedade.
  - Além disso, você pode configurar a navegação entre páginas no método OnStart. Por exemplo, você pode definir uma página de login como a primeira página e, após o login, navegar para a página principal.
 - Recursos Globais:
  - A classe App é um ótimo lugar para definir recursos globais, como estilos, temas ou serviços compartilhados.
Você pode usar o método OnAppThemeChanged para lidar com alterações de tema (claro/escuro) em todo o aplicativo.

----

- **Para que serve a AppShell.xaml?**

 - Nesse arquivos estaremos lidando com navegação através de diferentes tipos de layout. Em geral, é onde voce define seus menus, se serão Flyout ou TabBar, ou até mesmo os dois. Usamos esse arquivos se desejamos usar a navegação via [Shell](https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/shell/?view=net-maui-8.0), porém podemos descartá-lo e usar a navegação vanilla [via NavigationPage](https://learn.microsoft.com/en-us/dotnet/maui/user-interface/pages/navigationpage?view=net-maui-8.0). 

----

- **Para que serve o arquivo MauiProgram.cs?**

  - Assim como o arquivo Program.cs em AspNet Core, esse arquivo é o ponto de entrada para o seu app, é a primeira coisa a ser executada quando o usuário abre seu app.
  - Aqui podemos configurar fontes, container de injeção de dependências, serviços e biblioteca de terceiros.
  - Em resumo, é onde começa tudo.

----

## Vamos Respirar um pouco antes de prosseguir

E assim finalizo essa primeira parte com muita explicação sobre o que vamos ver nos próximos artigos. Muito obrigado por ter chegado até aqui, dúvidas, sugestões e correções fique a vontade em deixar nos comentários, nos vemos no próximo artigo!

[Repositório no Github](https://github.com/MarcosCostaDev/Maui-por-onde-comecar/tree/0b31593022f8f070246f4628d3668055c008786c)

Deixo esse vídeo para motivar vocês a ler esse artigo:
{% embed https://youtu.be/TRPBY_lxJfE?si=1cE2InP9FzsY9qEF&t=168 %}


Até a próxima! 👋