# Kotlin Multiplatform Mobile

Antes de falar sobre o que é o Kotlin Multiplatform Mobile (KMM), vou começar falando o que ele NÃO é.

### O KMM não é:

*   a nova bala de prata.
*   tentativa de matar o desenvolvimento nativo.
*   solução completa para aplicações multiplataforma (da UI até sua lógica de negócio).
*   não promete ser uma solução “*Build once deploy everywhere*”.
*   não promete simplificar ou recriar sua camada de UI.
*   framework para gerar aplicativos híbridos.

### O que é?

Antes de entrarmos no *Kotlin Multiplatform Mobile* (KMM), é importante entendermos o que é o Kotlin Multiplatform. Trata-se de uma *feature* ainda experimental do Kotlin, criada pela [JetBrains](https://www.jetbrains.com/pt-br/), que permite compartilhar código comum entre múltiplas plataformas (JavaScript, iOS, Android, desktop, etc).

De forma geral, o diagrama abaixo mostra como funciona a arquitetura do Kotlin Multiplatform.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700320030312/b403c043-5d83-43a8-b7ef-bcf228e851d4.png)

[https://kotlinlang.org/assets/images/reference/mpp/kotlin-multiplatform.png](https://kotlinlang.org/assets/images/reference/mpp/kotlin-multiplatform.png)

Na camada mais interna (***Common Kotlin***) temos todo o código Kotlin que funciona em todas as plataformas. Contém todo o código comum, incluindo HTTP, serialização e gerenciamento de [coroutines](https://kotlinlang.org/docs/reference/coroutines-overview.html).

Na camada intermediária (***Kotlin/JVM***, ***Kotlin/JS*** e ***Kotlin/Native***) temos todos os códigos Kotlin específicos necessários para cada plataforma, para garantir a interoperabilidade entre estas e o Kotlin.

Na camada mais externa (***JVM Code***, ***Native Code*** e ***Js Code***) temos todo código nativo específico de cada plataforma.

A partir desse contexto, surgiu o KMM sendo uma especialização do Kotlin Multiplatform focada na plataforma mobile.

A premissa é que você pode escrever sua lógica de negócio apenas uma vez em Kotlin e usar esse código tanto no Android quanto no iOS. Porém, ainda temos a necessidade de escrever códigos de UI específicos de acordo com cada plataforma.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700320031856/43dfec61-cf01-4647-a43d-9dee7f3b9ec2.png)

[https://kotlinlang.org/lp/mobile/static/sdk-811ad35a3742e58b40278b7a984fc289.svg](https://kotlinlang.org/lp/mobile/static/sdk-811ad35a3742e58b40278b7a984fc289.svg)

Na imagem acima podemos entender como o KMM é estruturado. Temos nosso código compartilhado (core e lógica de negócio) e o código específico de cada plataforma sendo usados por código nativo Android e/ou iOS (geralmente *views*).

### Padrão expect/actual

Caso seja necessário implementar algum código específico em cada plataforma (por exemplo, gerar um UUID ou acessar *bluetooth*) você tem a possibilidade de usar as declarações **e*xpect*** e ***actual***.

Esse mecanismo é parecido com uma [interface](https://medium.com/gdgcampinas/conceitos-b%C3%A1sicos-de-orienta%C3%A7%C3%A3o-a-objetos-b58809b2d809), onde o módulo compartilhado define uma declaração com a palavra chave ***expect*** e os módulos de cada plataforma proveem a declaração com a palavra chave ***actual*** escritos em Kotlin (e posteriormente compilados para Swift no caso do iOS).

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700320033541/6a480746-a621-4d94-a889-8971aa5cf6e9.png)

[https://kotlinlang.org/assets/images/reference/mpp/expect-actual.png](https://kotlinlang.org/assets/images/reference/mpp/expect-actual.png)

### Concorrentes? Ou não…

**Flutter**: solução ponta a ponta que usa Dart como linguagem. Com o mesmo código você consegue rapidamente gerar apps Android e iOS usando a mesma camada de UI. O código Dart é compilado em bibliotecas nativas (ARM e x86) que são incorporadas num projeto executor e a partir dele, podemos gerar nossos compilados como aab/apk (Android) ou ipa (iOS).

**React Native**: assim como o Flutter, também oferece uma solução ponta a ponta, mas usa React (JavaScript). Antigamente, a comunicação do Javascript com o nativo era feita a partir de uma *bridge* bidirecional, mas com a mudança de arquitetura essa comunicação agora é feita com JSI (JavaScript Interface), fazendo com que as funções sejam chamadas diretamente através do código JavaScript do React Native.

**Xamarin Native**: alternativa proposta pela Microsoft que mais se aproxima do KMM. A idéia também é que você tenha seu código de UI de cada plataforma e escreva a lógica de negócios compartilhada em C#, utilizando o Visual Studio. No caso do Android, os aplicativos são compilados de C# para **IL** (Linguagem Intermediária) e em seguida são compilados para um assembly nativo quando o app é iniciado. No iOS, o aplicativos são compilados diretamente de C# para assembly ARM nativo. Já o **Xamarin Forms** se propõe a ser uma solução ponta a ponta como Flutter e React Native usando C#.

### Hands-on

1.  Antes de começarmos a codar nosso aplicativo de exemplo, temos que preparar nosso ambiente de desenvolvimento.

*   Se você for usar apenas o código compartilhado e/ou código específico para Android, poderá usar qualquer computador com sistema operacional suportado pelo [Android Studio](https://developer.android.com/studio). Caso você queira usar código específico para iOS e/ou executar seu exemplo num simulador ou dispositivo físico, você vai precisar de um MacBook com macOS.
*   Instale o Android Studio 4.1 (RC1 ou superior). Você pode usar a versão 4.0, mas o plugin do KMM para essa versão é um pouco mais limitado.
*   Se você for escrever código específico para iOS e rodar o app iOS, instale o [Xcode](https://apps.apple.com/us/app/xcode/id497799835) 11.3 ou superior.
*   Atualize seu plugin do Kotlin para a versão 1.4.0 ou superior: no Android Studio selecione **Tools** | **Kotlin** | **Configure Kotlin Plugin Updates** e atualize para a última versão no canal de atualizações estáveis.
*   Instale o plugin do *Kotlin Multiplatform Mobile*: No Android Studio, selecione **Preferences** | **Plugins**, procure pelo plugin *Kotlin Multiplatform Mobile* em **Marketplace** e o instale.
*   Se você ainda não o fez, instale o [JDK](https://jdk.java.net/14/). Para ter certeza que você tem o JDK instalado, digite “**java -version”** no terminal.

2\. Com o ambiente configurado, estamos prontos para criar nosso exemplo.

*   No Android Studio selecione **File | New | New Project.**
*   Na tela de seleção de template, uma nova opção vai aparecer (KMM Application) e você deve selecioná-la.
*   Na próxima seção, informe o nome do projeto, pacote, localização e clique em *Finish* e aguarde a criação/configuração do projeto.
*   Na próxima tela vamos configurar o nome da nossa aplicação Android, iOS e do módulo compartilhado, e vamos clicar em *Finish* novamente.

3\. Depois de um longo inverno, nosso projeto foi criado. Vamos analisar o que aconteceu?

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700320034882/3a85afea-9183-4742-b469-251ead1d4a04.png)

Figura 1

Na Figura 1 podemos ver três componentes principais:

*   o módulo *shared*: que contém todo o código compartilhado entre Android e iOS, escrito em Kotlin.
*   o módulo androidApp: que contém nosso aplicativo Android.
*   o módulo iosApp: é um projeto do Xcode que contém o app iOS.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700320036383/192101af-f55b-4f49-adec-65a9c51b4278.png)

Figura 2

Explorando mais o módulo *shared* (Figura 2), nós vemos que ele contém todo o código comum que funciona em ambas as plataformas. Além disso, temos os pacotes androidMain que contém código específico para Android, incluindo as implementações do *actual.* Já no pacote iosMain, temos todo código específico para iOS, incluindo também as implementações do *actual* (escritas em Kotlin).

No nosso exemplo, no pacote commonMain dentro do módulo *shared* temos uma classe *Gretting* e uma classe *Platform*.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700320037719/50f4ee71-9246-4b20-8292-c13ffa144ae3.png)

Figura 3

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700320038907/2a798e00-3b18-4815-a7dd-4dc6966962b3.png)

Figura 4

Note que dentro da classe *Greeting*, temos um método *greeting()* (Figura 3) que retorna uma *string* e acessa um atributo da classe *Platform* (Figura 4), que por sua vez, não tem implementação nenhuma (observe o uso da palavra chave *expect*). Isso será resolvido nos pacotes específicos de cada plataforma, como veremos a seguir.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700320040379/4ee01a87-aeb4-4a70-8e1b-7c459504663d.png)

Figura 5

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700320041791/36b79d4b-cc1c-4aeb-af27-084ad361a50f.png)

Figura 6

Perceba como cada plataforma atribui o valor de *platform* conforme sua maneira (em Kotlin), usando a palavra chave *actual* (Figura 5 e 6).

Atenção com o iOS aqui. Caso você não tenha o Xcode instalado, podem aparecer alguns erros (linhas vermelhas), mas isso não será problema para compilar o projeto.

Mas, como fica o uso disso nos projetos nativos? Veja um exemplo no Android:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700320043286/0ac792f4-d7a1-4c3a-a639-e6be15532346.png)

Figura 7

Estamos chamando o método *greet()*, que por sua vez chama o método *greeting* do módulo compartilhado (Figura 7).

Veja o mesmo exemplo no projeto do iOS (Figura 8):

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700320044552/b9137669-b577-420e-b90f-8fb4c6bc3249.png)

Figura 8

Se tivermos usando um MacBook com Xcode configurado, podemos rodar nosso app Android e iOS pelo Android Studio e aqui está o resultado (Figura 9).

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1700320046127/4ef953fa-5e10-4cd9-bee8-3483d2970f4a.png)

Figura 9

### Últimas palavras…

O objetivo desse artigo foi dar uma pequena introdução do KMM e mostrar suas possibilidades. Durante meus estudos, vi como a documentação está evoluindo rapidamente e como a JetBrains está se esforçando para que a solução seja adotada pelo maior número de pessoas possível. Eles dão sugestões de como migrar para o KMM, como organizar processos, impactos e problemas que você pode ter no time e até mesmo como introduzir o assunto com os desenvolvedores.

Conhecimento não pesa e não engorda…mesmo sendo uma pessoa que desenvolve apps nativos, acredito que valha a pena se informar sobre as soluções que estão surgindo no nosso ecossistema para ampliar o nosso repertório e nos tornar mais aptos para poder tomar melhores decisões.

Aqui estão os links que me inspiraram e que podem lhe ajudar a descobrir um pouco mais sobre o assunto.

[Multiplatform programming](https://kotlinlang.org/docs/reference/multiplatform.html)

[Kotlin Multiplatform Mobile](https://kotlinlang.org/lp/mobile/)

[Connect to platform-specific APIs](https://kotlinlang.org/docs/reference/mpp-connect-to-apis.html)

[Have you tried Kotlin Multiplatform?](https://www.linkedin.com/pulse/have-you-tried-kotlin-multiplatform-nate-ebel/)

[Blog do Matheus Castiglioni | React Native é nativo?](https://blog.matheuscastiglioni.com.br/react-native-e-nativo/)

[Xamarin.Android — Xamarin](https://docs.microsoft.com/pt-br/xamarin/android/)

[Download Android Studio and SDK tools](https://developer.android.com/studio)

[‎Xcode on the Mac App Store](https://apps.apple.com/us/app/xcode/id497799835)

[JDK 14.0.2 GA Release](https://jdk.java.net/14/)

[KMM documentation](https://kotlinlang.org/docs/mobile/home.html)

[JetBrains](https://www.jetbrains.com/pt-br/)

Imagem de [Peggy und Marco Lachmann-Anke](https://pixabay.com/pt/users/peggy_marco-1553824/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=1013616) por [Pixabay](https://pixabay.com/pt/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=1013616)
