SlideShare a Scribd company logo
1 of 46
Nelson Glauber
Android GDE
@nglauber
Seu primeiro app
Android e iOS com
Compose Multiplatform
O que é Kotlin Multiplatform?
• O Kotlin Multiplatform (ou simplesmente KMP) é uma tecnologia
desenvolvida pela Jetbrains para desenvolvimento de aplicações multi-
plataforma.
• Isso signi
fi
ca que é possível compartilhar código entre várias plataformas
(incluindo a parte do servidor)
Cross-Platform ou Nativo? E agora?
• Com o KMP você pode ter OS DOIS! Cross-Platform E Nativo. É possível:
1. compartilhar parte da lógica de negócio e deixar a UI nativa;
2. compartilhar toda a lógica de negócio e deixar a UI nativa;
3. ou compartilhar a lógica de negócio E a UI.
Kotlin/Native
Kotlin/JVM
APIs : Jetpack Compose x Compose Multiplatform
• Compose Multiplatform APIs são quase as mesmas das API de Jetpack
Compose
• Então todo o seu conhecimento em Jetpack Compose pode ser
reaproveitado
kdoctor
Android Studio + KMP Plugin
https://www.jetbrains.com/
fl
eet
• Fleet está disponível para
Windows, Mac and Linux
• Permite criar uma sessão
colaborativa com outro dev.
• Code completion e Refactoring
para código Swift
• Cross-Language navigation
(Kotlin <-> Swift)
• Cross-Language debugging
(Kotlin <-> Swift)
• Free durante o public preview
kmp.jetbrains.com
Estrutura do Projeto
• composeApp
• commonMain: código comum compartilhado entre as
plataformas. Ex.: expect declarations, ou de
fi
nição de
interfaces entre plataformas. As únicas dependências são
bibliotecas multi-plataforma.
• androidMain: implementação especí
fi
ca para Android (actual
functions e implementação de interface especí
fi
ca para
Android)
• iosMain: implementação especí
fi
ca para iOS (actual functions
e implementação de interface especí
fi
ca para Android).
• iosApp
Estrutura do Projeto
• commonMain + androidMain = Android
• commonMain + iosMain = iOS
List of Books
Books List
View Model
https://github.com/nglauber/dominando_android3/
blob/master/livros_novatec.json
Dependências
• Ktor para requisições web (https://github.com/ktorio/ktor)
• Voyager implementar View Model e Navegação (https://github.com/
adrielcafe/voyager)
• Kamel para carregamento de imagens (https://github.com/Kamel-Media/
Kamel)
[versions]
...
ktor = "2.3.6"
voyager = "1.0.0"
kamel = "0.8.3"
[libraries]
...
ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" }
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" }
ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" }
ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" }
cafe-adriel-voyager-navigator = { module = "cafe.adriel.voyager:voyager-navigator", version.ref = "voyager" }
cafe-adriel-voyager-screenmodel = { module = "cafe.adriel.voyager:voyager-screenmodel", version.ref = "voyager" }
kamel = { module = "media.kamel:kamel-image", version.ref = "kamel" }
[plugins]
...
kotlinxSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin"}
gradle/libs.version.toml
plugins {
...
alias(libs.plugins.kotlinxSerialization)
}
kotlin {
...
sourceSets {
androidMain.dependencies {
...
implementation(libs.ktor.client.okhttp)
}
iosMain.dependencies {
implementation(libs.ktor.client.darwin)
}
commonMain.dependencies {
...
implementation(libs.ktor.client.core)
implementation(libs.ktor.client.content.negotiation)
implementation(libs.ktor.serialization.kotlinx.json)
implementation(libs.cafe.adriel.voyager.navigator)
implementation(libs.cafe.adriel.voyager.screenmodel)
implementation(libs.kamel)
}
}
}
composeApp/build.gradle.kts
O projeto
• Mostrar o JSON que será consumido (https://raw.githubusercontent.com/
nglauber/dominando_android3/master/livros_novatec.json)
Data Classes
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class Publisher(
@SerialName("novatec")
val categories: List<Category>
)
@Serializable
data class Category(
@SerialName("categoria")
val name: String,
@SerialName("livros")
val books: List<Book>
)
@Serializable
data class Book(
@SerialName("ano")
val year: Int,
@SerialName("autor")
val author: String,
@SerialName("capa")
val coverUrl: String,
@SerialName("paginas")
val pages: Int,
@SerialName("titulo")
val title: String
)
ViewModel e Networking
class BooksListViewModel: ScreenModel {
private val jsonUrl = "https://raw.githubusercontent.com/nglauber/dominando_android3/master/
livros_novatec.json"
private val httpClient = HttpClient {
install(ContentNegotiation) {
json()
}
}
override fun onDispose() {
super.onDispose()
httpClient.close()
}
private suspend fun loadPublisher(): Publisher {
return try {
httpClient.get(jsonUrl).body()
} catch (e: NoTransformationFoundException) {
val jsonString = httpClient.get(jsonUrl).body<String>()
Json.decodeFromString(jsonString)
}
}
}
Solução técnica adaptativa…🤭
ViewModel e UI State
data class BooksListUiState(
val books: List<Book>
)
class BooksListViewModel : ScreenModel {
private val _uiState = MutableStateFlow(BooksListUiState(emptyList()))
val uiState: StateFlow<BooksListUiState> = _uiState.asStateFlow()
init {
updateBookList()
}
fun updateBookList() {
screenModelScope.launch {
val publisher = loadPublisher()
val books = publisher.categories.flatMap { it.books }
_uiState.update {
it.copy(books = books)
}
}
}
...
}
ViewModel e UI State
data class BooksListUiState(
val books: List<Book> = emptyList(),
)
class BooksListViewModel : StateScreenModel<BooksListUiState>(
BooksListUiState(emptyList())
) {
init {
updateBookList()
}
fun updateBookList() {
screenModelScope.launch {
val publisher = loadPublisher()
val books = publisher.categories.flatMap { it.books }
mutableState.update {
it.copy(books = books)
}
}
}
...
}
class BooksListScreen : Screen {
@Composable
override fun Content() {
val viewModel = rememberScreenModel {
BooksListViewModel()
}
val uiState by viewModel.state.collectAsState()
LazyColumn {
items(uiState.books) {
Text(it.title)
}
}
}
}
Tela de listagem de livros
@Composable
fun App() {
MaterialTheme {
Navigator(BooksListScreen())
}
}
Tela de listagem de livros
@Composable
fun BookListItem(book: Book) {
Row(Modifier.padding(8.dp)) {
KamelImage(
resource = asyncPainterResource(book.coverUrl),
contentDescription = "Capa do livro ${book.title}",
modifier = Modifier.weight(.3f).aspectRatio(3 / 4f)
)
Spacer(Modifier.width(8.dp))
Column(Modifier.weight(.7f)) {
Text(book.title, style = MaterialTheme.typography.h6)
Text(book.author)
Text("Ano: ${book.year} | Pages: ${book.pages}")
}
}
}
Filtrando os resultados
data class BooksListUiState(
val publisher: Publisher = Publisher(emptyList()),
val selectedCategory: String? = null,
) {
val categories: List<Category> = publisher.categories
val books: List<Book> =
if (selectedCategory == null)
categories.flatMap { it.books }
else
categories.filter { it.name == selectedCategory }
.flatMap { it.books }
}
fun updateBookList() {
screenModelScope.launch {
val publisher = loadPublisher()
mutableState.update {
it.copy(publisher = publisher)
}
}
}
fun selectCategory(category: String) {
mutableState.update { state ->
if (state.selectedCategory == category) {
state.copy(selectedCategory = null)
} else {
state.copy(selectedCategory = category)
}
}
}
Filtrando os resultados
val viewModel = rememberScreenModel {
BooksListViewModel()
}
val uiState by viewModel.state.collectAsState()
Column {
LazyRow {
items(uiState.categories) {
Button(onClick = {
viewModel.selectCategory(it.name)
}) {
Text(it.name)
}
}
}
LazyColumn {
items(uiState.books) {
BookListItem(book = it)
}
}
}
Navegando para tela de detalhes
class BooksDetailsScreen(private val book: Book) : Screen {
@Composable
override fun Content() {
val navigator = LocalNavigator.currentOrThrow
Column {
Text(book.title)
Text(book.author)
Button(onClick = {
navigator.pop()
}) {
Text("Voltar")
}
}
}
}
@Composable
fun BookListItem(book: Book) {
val navigator = LocalNavigator.currentOrThrow
Row(
Modifier.padding(8.dp).clickable {
navigator.push(BooksDetailsScreen(book))
},
) { ...
Google Libs
• Google está portando suas bibliotecas para KMP
• Annotations
• Collections
• Paging
github.com/terrakok/kmp-awesome
Navigation
• Voyager (https://github.com/adrielcafe/voyager)
• PreCompose (https://github.com/Tlaster/PreCompose)
Resource Management and more…
• Permissions (https://github.com/icerockdev/moko-permissions)
• MVVM (https://github.com/icerockdev/moko-mvvm)
• Resources (https://github.com/icerockdev/moko-resources)
• Biometry (https://github.com/icerockdev/moko-biometry)
• Media (https://github.com/icerockdev/moko-media)
• Geolocation (https://github.com/icerockdev/moko-geo)
Image Loading
• Compose Image Loader (https://github.com/qdsfdhvh/compose-
imageloader)
• Kamel (https://github.com/Kamel-Media/Kamel)
• Coil (https://github.com/coil-kt/coil) (not ready yet)
Networking
• Ktor (https://github.com/ktorio/ktor)
• Ktor
fi
t (https://github.com/Foso/Ktor
fi
t)
Persistence
• SQLDelight (https://github.com/cashapp/sqldelight)
• Kstore (https://github.com/xxfast/kstore)
• MultiPlatform Settings (https://github.com/russhwolf/multiplatform-
settings)
• Google Data Store (https://developer.android.com/jetpack/androidx/
releases/datastore)
Compose Look and Feel
• https://github.com/alexzhirkevich/compose-cupertino
iOS Gradual adoption
iOS
Referências
• The state of Kotlin Multiplatform (https://www.youtube.com/watch?
v=bz4cQeaXmsI)
• Getting Started With KMP: Build Apps for iOS and Android With Shared Logic
and Native UIs (https://www.youtube.com/watch?v=zE2LIAUisRI)
• Build Apps for iOS, Android, and Desktop With Compose Multiplatform
(https://www.youtube.com/watch?v=IGuVIRZzVTk)
• Build an iOS & Android app in 100% Kotlin with Compose Multiplatform
(https://www.youtube.com/watch?v=5_W5YKPShZ4)
Obrigado!
Dúvidas?
Nelson Glauber
Android GDE
@nglauber

More Related Content

Similar to Seu primeiro app Android e iOS com Compose Multiplatform

TDC 2012 - Patterns e Anti-Patterns em Ruby
TDC 2012 - Patterns e Anti-Patterns em RubyTDC 2012 - Patterns e Anti-Patterns em Ruby
TDC 2012 - Patterns e Anti-Patterns em RubyFabio Akita
 
Groovy Ecosystem - JFokus 2011 - Guillaume Laforge
Groovy Ecosystem - JFokus 2011 - Guillaume LaforgeGroovy Ecosystem - JFokus 2011 - Guillaume Laforge
Groovy Ecosystem - JFokus 2011 - Guillaume LaforgeGuillaume Laforge
 
A single language for backend and frontend from AngularJS to cloud with Clau...
A single language for backend and frontend  from AngularJS to cloud with Clau...A single language for backend and frontend  from AngularJS to cloud with Clau...
A single language for backend and frontend from AngularJS to cloud with Clau...Corley S.r.l.
 
A single language for backend and frontend from AngularJS to cloud with Clau...
A single language for backend and frontend  from AngularJS to cloud with Clau...A single language for backend and frontend  from AngularJS to cloud with Clau...
A single language for backend and frontend from AngularJS to cloud with Clau...Walter Dal Mut
 
MongoDB Aggregation Framework
MongoDB Aggregation FrameworkMongoDB Aggregation Framework
MongoDB Aggregation FrameworkCaserta
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...Fabio Franzini
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackNelson Glauber Leal
 
Advanced Technology for Web Application Design
Advanced Technology for Web Application DesignAdvanced Technology for Web Application Design
Advanced Technology for Web Application DesignBryce Kerley
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScriptAndrew Dupont
 
Datagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and BackgridDatagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and BackgridGiorgio Cefaro
 
Datagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and BackgridDatagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and Backgrideugenio pombi
 
G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門Tsuyoshi Yamamoto
 
Deep Dive Into Swift
Deep Dive Into SwiftDeep Dive Into Swift
Deep Dive Into SwiftSarath C
 
DSL - expressive syntax on top of a clean semantic model
DSL - expressive syntax on top of a clean semantic modelDSL - expressive syntax on top of a clean semantic model
DSL - expressive syntax on top of a clean semantic modelDebasish Ghosh
 
Building Kafka Connectors with Kotlin: A Step-by-Step Guide to Creation and D...
Building Kafka Connectors with Kotlin: A Step-by-Step Guide to Creation and D...Building Kafka Connectors with Kotlin: A Step-by-Step Guide to Creation and D...
Building Kafka Connectors with Kotlin: A Step-by-Step Guide to Creation and D...HostedbyConfluent
 
Framework agnostic application Will it fit with Symfony? - Symfony live warsa...
Framework agnostic application Will it fit with Symfony? - Symfony live warsa...Framework agnostic application Will it fit with Symfony? - Symfony live warsa...
Framework agnostic application Will it fit with Symfony? - Symfony live warsa...Dariusz Drobisz
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot CampTroy Miles
 
Phoenix for Rails Devs
Phoenix for Rails DevsPhoenix for Rails Devs
Phoenix for Rails DevsDiacode
 

Similar to Seu primeiro app Android e iOS com Compose Multiplatform (20)

TDC 2012 - Patterns e Anti-Patterns em Ruby
TDC 2012 - Patterns e Anti-Patterns em RubyTDC 2012 - Patterns e Anti-Patterns em Ruby
TDC 2012 - Patterns e Anti-Patterns em Ruby
 
Groovy Ecosystem - JFokus 2011 - Guillaume Laforge
Groovy Ecosystem - JFokus 2011 - Guillaume LaforgeGroovy Ecosystem - JFokus 2011 - Guillaume Laforge
Groovy Ecosystem - JFokus 2011 - Guillaume Laforge
 
A single language for backend and frontend from AngularJS to cloud with Clau...
A single language for backend and frontend  from AngularJS to cloud with Clau...A single language for backend and frontend  from AngularJS to cloud with Clau...
A single language for backend and frontend from AngularJS to cloud with Clau...
 
A single language for backend and frontend from AngularJS to cloud with Clau...
A single language for backend and frontend  from AngularJS to cloud with Clau...A single language for backend and frontend  from AngularJS to cloud with Clau...
A single language for backend and frontend from AngularJS to cloud with Clau...
 
MongoDB Aggregation Framework
MongoDB Aggregation FrameworkMongoDB Aggregation Framework
MongoDB Aggregation Framework
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com Jetpack
 
Advanced Technology for Web Application Design
Advanced Technology for Web Application DesignAdvanced Technology for Web Application Design
Advanced Technology for Web Application Design
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScript
 
Datagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and BackgridDatagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and Backgrid
 
Datagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and BackgridDatagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and Backgrid
 
G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門G*ワークショップ in 仙台 Grails(とことん)入門
G*ワークショップ in 仙台 Grails(とことん)入門
 
Deep Dive Into Swift
Deep Dive Into SwiftDeep Dive Into Swift
Deep Dive Into Swift
 
DSL - expressive syntax on top of a clean semantic model
DSL - expressive syntax on top of a clean semantic modelDSL - expressive syntax on top of a clean semantic model
DSL - expressive syntax on top of a clean semantic model
 
Building Kafka Connectors with Kotlin: A Step-by-Step Guide to Creation and D...
Building Kafka Connectors with Kotlin: A Step-by-Step Guide to Creation and D...Building Kafka Connectors with Kotlin: A Step-by-Step Guide to Creation and D...
Building Kafka Connectors with Kotlin: A Step-by-Step Guide to Creation and D...
 
Framework agnostic application Will it fit with Symfony? - Symfony live warsa...
Framework agnostic application Will it fit with Symfony? - Symfony live warsa...Framework agnostic application Will it fit with Symfony? - Symfony live warsa...
Framework agnostic application Will it fit with Symfony? - Symfony live warsa...
 
Ams adapters
Ams adaptersAms adapters
Ams adapters
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
 
Phoenix for Rails Devs
Phoenix for Rails DevsPhoenix for Rails Devs
Phoenix for Rails Devs
 
Sprockets
SprocketsSprockets
Sprockets
 

More from Nelson Glauber Leal

Desenvolvimento Moderno de Aplicações Android 2023
Desenvolvimento Moderno de Aplicações Android 2023Desenvolvimento Moderno de Aplicações Android 2023
Desenvolvimento Moderno de Aplicações Android 2023Nelson Glauber Leal
 
Novidades incríveis do Android em 2023
Novidades incríveis do Android em 2023Novidades incríveis do Android em 2023
Novidades incríveis do Android em 2023Nelson Glauber Leal
 
Novidades das Bibliotecas Jetpack do Android (2021)
Novidades das Bibliotecas Jetpack do Android (2021)Novidades das Bibliotecas Jetpack do Android (2021)
Novidades das Bibliotecas Jetpack do Android (2021)Nelson Glauber Leal
 
Android Jetpack Compose - Turkey 2021
Android Jetpack Compose - Turkey 2021Android Jetpack Compose - Turkey 2021
Android Jetpack Compose - Turkey 2021Nelson Glauber Leal
 
Jetpack Compose a new way to implement UI on Android
Jetpack Compose a new way to implement UI on AndroidJetpack Compose a new way to implement UI on Android
Jetpack Compose a new way to implement UI on AndroidNelson Glauber Leal
 
Jetpack Compose a nova forma de implementar UI no Android
Jetpack Compose a nova forma de implementar UI no AndroidJetpack Compose a nova forma de implementar UI no Android
Jetpack Compose a nova forma de implementar UI no AndroidNelson Glauber Leal
 
Aplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackAplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackNelson Glauber Leal
 
Aplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackAplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackNelson Glauber Leal
 
O que é preciso para ser um desenvolvedor Android
O que é preciso para ser um desenvolvedor AndroidO que é preciso para ser um desenvolvedor Android
O que é preciso para ser um desenvolvedor AndroidNelson Glauber Leal
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackNelson Glauber Leal
 
Aplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e JetpackAplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e JetpackNelson Glauber Leal
 
Mastering Kotlin Standard Library
Mastering Kotlin Standard LibraryMastering Kotlin Standard Library
Mastering Kotlin Standard LibraryNelson Glauber Leal
 
Aplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & JetpackAplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & JetpackNelson Glauber Leal
 
Introdução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com KotlinIntrodução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com KotlinNelson Glauber Leal
 
Persisting Data on SQLite using Room
Persisting Data on SQLite using RoomPersisting Data on SQLite using Room
Persisting Data on SQLite using RoomNelson Glauber Leal
 
Arquitetando seu aplicativo Android com Jetpack
Arquitetando seu aplicativo Android com JetpackArquitetando seu aplicativo Android com Jetpack
Arquitetando seu aplicativo Android com JetpackNelson Glauber Leal
 
Desenvolvimento Moderno de Aplicativos Android
Desenvolvimento Moderno de Aplicativos AndroidDesenvolvimento Moderno de Aplicativos Android
Desenvolvimento Moderno de Aplicativos AndroidNelson Glauber Leal
 
Desenvolvimento Moderno de aplicativos Android
Desenvolvimento Moderno de aplicativos AndroidDesenvolvimento Moderno de aplicativos Android
Desenvolvimento Moderno de aplicativos AndroidNelson Glauber Leal
 
Turbinando o desenvolvimento Android com Kotlin
Turbinando o desenvolvimento Android com KotlinTurbinando o desenvolvimento Android com Kotlin
Turbinando o desenvolvimento Android com KotlinNelson Glauber Leal
 
Tudo que você precisa saber sobre Constraint Layout
Tudo que você precisa saber sobre Constraint LayoutTudo que você precisa saber sobre Constraint Layout
Tudo que você precisa saber sobre Constraint LayoutNelson Glauber Leal
 

More from Nelson Glauber Leal (20)

Desenvolvimento Moderno de Aplicações Android 2023
Desenvolvimento Moderno de Aplicações Android 2023Desenvolvimento Moderno de Aplicações Android 2023
Desenvolvimento Moderno de Aplicações Android 2023
 
Novidades incríveis do Android em 2023
Novidades incríveis do Android em 2023Novidades incríveis do Android em 2023
Novidades incríveis do Android em 2023
 
Novidades das Bibliotecas Jetpack do Android (2021)
Novidades das Bibliotecas Jetpack do Android (2021)Novidades das Bibliotecas Jetpack do Android (2021)
Novidades das Bibliotecas Jetpack do Android (2021)
 
Android Jetpack Compose - Turkey 2021
Android Jetpack Compose - Turkey 2021Android Jetpack Compose - Turkey 2021
Android Jetpack Compose - Turkey 2021
 
Jetpack Compose a new way to implement UI on Android
Jetpack Compose a new way to implement UI on AndroidJetpack Compose a new way to implement UI on Android
Jetpack Compose a new way to implement UI on Android
 
Jetpack Compose a nova forma de implementar UI no Android
Jetpack Compose a nova forma de implementar UI no AndroidJetpack Compose a nova forma de implementar UI no Android
Jetpack Compose a nova forma de implementar UI no Android
 
Aplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackAplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & Jetpack
 
Aplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & JetpackAplicações assíncronas no Android com
Coroutines & Jetpack
Aplicações assíncronas no Android com
Coroutines & Jetpack
 
O que é preciso para ser um desenvolvedor Android
O que é preciso para ser um desenvolvedor AndroidO que é preciso para ser um desenvolvedor Android
O que é preciso para ser um desenvolvedor Android
 
Arquitetando seu app Android com Jetpack
Arquitetando seu app Android com JetpackArquitetando seu app Android com Jetpack
Arquitetando seu app Android com Jetpack
 
Aplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e JetpackAplicações Assíncronas no Android com Coroutines e Jetpack
Aplicações Assíncronas no Android com Coroutines e Jetpack
 
Mastering Kotlin Standard Library
Mastering Kotlin Standard LibraryMastering Kotlin Standard Library
Mastering Kotlin Standard Library
 
Aplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & JetpackAplicações assíncronas no Android com Coroutines & Jetpack
Aplicações assíncronas no Android com Coroutines & Jetpack
 
Introdução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com KotlinIntrodução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com Kotlin
 
Persisting Data on SQLite using Room
Persisting Data on SQLite using RoomPersisting Data on SQLite using Room
Persisting Data on SQLite using Room
 
Arquitetando seu aplicativo Android com Jetpack
Arquitetando seu aplicativo Android com JetpackArquitetando seu aplicativo Android com Jetpack
Arquitetando seu aplicativo Android com Jetpack
 
Desenvolvimento Moderno de Aplicativos Android
Desenvolvimento Moderno de Aplicativos AndroidDesenvolvimento Moderno de Aplicativos Android
Desenvolvimento Moderno de Aplicativos Android
 
Desenvolvimento Moderno de aplicativos Android
Desenvolvimento Moderno de aplicativos AndroidDesenvolvimento Moderno de aplicativos Android
Desenvolvimento Moderno de aplicativos Android
 
Turbinando o desenvolvimento Android com Kotlin
Turbinando o desenvolvimento Android com KotlinTurbinando o desenvolvimento Android com Kotlin
Turbinando o desenvolvimento Android com Kotlin
 
Tudo que você precisa saber sobre Constraint Layout
Tudo que você precisa saber sobre Constraint LayoutTudo que você precisa saber sobre Constraint Layout
Tudo que você precisa saber sobre Constraint Layout
 

Recently uploaded

Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Intelisync
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...aditisharan08
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 

Recently uploaded (20)

Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 

Seu primeiro app Android e iOS com Compose Multiplatform

  • 1. Nelson Glauber Android GDE @nglauber Seu primeiro app Android e iOS com Compose Multiplatform
  • 2. O que é Kotlin Multiplatform? • O Kotlin Multiplatform (ou simplesmente KMP) é uma tecnologia desenvolvida pela Jetbrains para desenvolvimento de aplicações multi- plataforma. • Isso signi fi ca que é possível compartilhar código entre várias plataformas (incluindo a parte do servidor)
  • 3.
  • 4. Cross-Platform ou Nativo? E agora? • Com o KMP você pode ter OS DOIS! Cross-Platform E Nativo. É possível: 1. compartilhar parte da lógica de negócio e deixar a UI nativa; 2. compartilhar toda a lógica de negócio e deixar a UI nativa; 3. ou compartilhar a lógica de negócio E a UI.
  • 5.
  • 7.
  • 8.
  • 9.
  • 10. APIs : Jetpack Compose x Compose Multiplatform • Compose Multiplatform APIs são quase as mesmas das API de Jetpack Compose • Então todo o seu conhecimento em Jetpack Compose pode ser reaproveitado
  • 12. Android Studio + KMP Plugin
  • 13. https://www.jetbrains.com/ fl eet • Fleet está disponível para Windows, Mac and Linux • Permite criar uma sessão colaborativa com outro dev. • Code completion e Refactoring para código Swift • Cross-Language navigation (Kotlin <-> Swift) • Cross-Language debugging (Kotlin <-> Swift) • Free durante o public preview
  • 15. Estrutura do Projeto • composeApp • commonMain: código comum compartilhado entre as plataformas. Ex.: expect declarations, ou de fi nição de interfaces entre plataformas. As únicas dependências são bibliotecas multi-plataforma. • androidMain: implementação especí fi ca para Android (actual functions e implementação de interface especí fi ca para Android) • iosMain: implementação especí fi ca para iOS (actual functions e implementação de interface especí fi ca para Android). • iosApp
  • 16. Estrutura do Projeto • commonMain + androidMain = Android • commonMain + iosMain = iOS
  • 17.
  • 18. List of Books Books List View Model https://github.com/nglauber/dominando_android3/ blob/master/livros_novatec.json
  • 19. Dependências • Ktor para requisições web (https://github.com/ktorio/ktor) • Voyager implementar View Model e Navegação (https://github.com/ adrielcafe/voyager) • Kamel para carregamento de imagens (https://github.com/Kamel-Media/ Kamel)
  • 20. [versions] ... ktor = "2.3.6" voyager = "1.0.0" kamel = "0.8.3" [libraries] ... ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" } ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" } ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" } ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" } cafe-adriel-voyager-navigator = { module = "cafe.adriel.voyager:voyager-navigator", version.ref = "voyager" } cafe-adriel-voyager-screenmodel = { module = "cafe.adriel.voyager:voyager-screenmodel", version.ref = "voyager" } kamel = { module = "media.kamel:kamel-image", version.ref = "kamel" } [plugins] ... kotlinxSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin"} gradle/libs.version.toml
  • 21. plugins { ... alias(libs.plugins.kotlinxSerialization) } kotlin { ... sourceSets { androidMain.dependencies { ... implementation(libs.ktor.client.okhttp) } iosMain.dependencies { implementation(libs.ktor.client.darwin) } commonMain.dependencies { ... implementation(libs.ktor.client.core) implementation(libs.ktor.client.content.negotiation) implementation(libs.ktor.serialization.kotlinx.json) implementation(libs.cafe.adriel.voyager.navigator) implementation(libs.cafe.adriel.voyager.screenmodel) implementation(libs.kamel) } } } composeApp/build.gradle.kts
  • 22. O projeto • Mostrar o JSON que será consumido (https://raw.githubusercontent.com/ nglauber/dominando_android3/master/livros_novatec.json)
  • 23. Data Classes import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable data class Publisher( @SerialName("novatec") val categories: List<Category> ) @Serializable data class Category( @SerialName("categoria") val name: String, @SerialName("livros") val books: List<Book> ) @Serializable data class Book( @SerialName("ano") val year: Int, @SerialName("autor") val author: String, @SerialName("capa") val coverUrl: String, @SerialName("paginas") val pages: Int, @SerialName("titulo") val title: String )
  • 24. ViewModel e Networking class BooksListViewModel: ScreenModel { private val jsonUrl = "https://raw.githubusercontent.com/nglauber/dominando_android3/master/ livros_novatec.json" private val httpClient = HttpClient { install(ContentNegotiation) { json() } } override fun onDispose() { super.onDispose() httpClient.close() } private suspend fun loadPublisher(): Publisher { return try { httpClient.get(jsonUrl).body() } catch (e: NoTransformationFoundException) { val jsonString = httpClient.get(jsonUrl).body<String>() Json.decodeFromString(jsonString) } } } Solução técnica adaptativa…🤭
  • 25. ViewModel e UI State data class BooksListUiState( val books: List<Book> ) class BooksListViewModel : ScreenModel { private val _uiState = MutableStateFlow(BooksListUiState(emptyList())) val uiState: StateFlow<BooksListUiState> = _uiState.asStateFlow() init { updateBookList() } fun updateBookList() { screenModelScope.launch { val publisher = loadPublisher() val books = publisher.categories.flatMap { it.books } _uiState.update { it.copy(books = books) } } } ... }
  • 26. ViewModel e UI State data class BooksListUiState( val books: List<Book> = emptyList(), ) class BooksListViewModel : StateScreenModel<BooksListUiState>( BooksListUiState(emptyList()) ) { init { updateBookList() } fun updateBookList() { screenModelScope.launch { val publisher = loadPublisher() val books = publisher.categories.flatMap { it.books } mutableState.update { it.copy(books = books) } } } ... }
  • 27. class BooksListScreen : Screen { @Composable override fun Content() { val viewModel = rememberScreenModel { BooksListViewModel() } val uiState by viewModel.state.collectAsState() LazyColumn { items(uiState.books) { Text(it.title) } } } } Tela de listagem de livros @Composable fun App() { MaterialTheme { Navigator(BooksListScreen()) } }
  • 28. Tela de listagem de livros @Composable fun BookListItem(book: Book) { Row(Modifier.padding(8.dp)) { KamelImage( resource = asyncPainterResource(book.coverUrl), contentDescription = "Capa do livro ${book.title}", modifier = Modifier.weight(.3f).aspectRatio(3 / 4f) ) Spacer(Modifier.width(8.dp)) Column(Modifier.weight(.7f)) { Text(book.title, style = MaterialTheme.typography.h6) Text(book.author) Text("Ano: ${book.year} | Pages: ${book.pages}") } } }
  • 29. Filtrando os resultados data class BooksListUiState( val publisher: Publisher = Publisher(emptyList()), val selectedCategory: String? = null, ) { val categories: List<Category> = publisher.categories val books: List<Book> = if (selectedCategory == null) categories.flatMap { it.books } else categories.filter { it.name == selectedCategory } .flatMap { it.books } } fun updateBookList() { screenModelScope.launch { val publisher = loadPublisher() mutableState.update { it.copy(publisher = publisher) } } } fun selectCategory(category: String) { mutableState.update { state -> if (state.selectedCategory == category) { state.copy(selectedCategory = null) } else { state.copy(selectedCategory = category) } } }
  • 30. Filtrando os resultados val viewModel = rememberScreenModel { BooksListViewModel() } val uiState by viewModel.state.collectAsState() Column { LazyRow { items(uiState.categories) { Button(onClick = { viewModel.selectCategory(it.name) }) { Text(it.name) } } } LazyColumn { items(uiState.books) { BookListItem(book = it) } } }
  • 31. Navegando para tela de detalhes class BooksDetailsScreen(private val book: Book) : Screen { @Composable override fun Content() { val navigator = LocalNavigator.currentOrThrow Column { Text(book.title) Text(book.author) Button(onClick = { navigator.pop() }) { Text("Voltar") } } } } @Composable fun BookListItem(book: Book) { val navigator = LocalNavigator.currentOrThrow Row( Modifier.padding(8.dp).clickable { navigator.push(BooksDetailsScreen(book)) }, ) { ...
  • 32.
  • 33. Google Libs • Google está portando suas bibliotecas para KMP • Annotations • Collections • Paging
  • 35. Navigation • Voyager (https://github.com/adrielcafe/voyager) • PreCompose (https://github.com/Tlaster/PreCompose)
  • 36. Resource Management and more… • Permissions (https://github.com/icerockdev/moko-permissions) • MVVM (https://github.com/icerockdev/moko-mvvm) • Resources (https://github.com/icerockdev/moko-resources) • Biometry (https://github.com/icerockdev/moko-biometry) • Media (https://github.com/icerockdev/moko-media) • Geolocation (https://github.com/icerockdev/moko-geo)
  • 37. Image Loading • Compose Image Loader (https://github.com/qdsfdhvh/compose- imageloader) • Kamel (https://github.com/Kamel-Media/Kamel) • Coil (https://github.com/coil-kt/coil) (not ready yet)
  • 38. Networking • Ktor (https://github.com/ktorio/ktor) • Ktor fi t (https://github.com/Foso/Ktor fi t)
  • 39. Persistence • SQLDelight (https://github.com/cashapp/sqldelight) • Kstore (https://github.com/xxfast/kstore) • MultiPlatform Settings (https://github.com/russhwolf/multiplatform- settings) • Google Data Store (https://developer.android.com/jetpack/androidx/ releases/datastore)
  • 40. Compose Look and Feel • https://github.com/alexzhirkevich/compose-cupertino
  • 42. iOS
  • 43.
  • 44.
  • 45. Referências • The state of Kotlin Multiplatform (https://www.youtube.com/watch? v=bz4cQeaXmsI) • Getting Started With KMP: Build Apps for iOS and Android With Shared Logic and Native UIs (https://www.youtube.com/watch?v=zE2LIAUisRI) • Build Apps for iOS, Android, and Desktop With Compose Multiplatform (https://www.youtube.com/watch?v=IGuVIRZzVTk) • Build an iOS & Android app in 100% Kotlin with Compose Multiplatform (https://www.youtube.com/watch?v=5_W5YKPShZ4)