Distrito Telefónica. Hub de Innovación y Talento
Kotlin
Herramientas
Estructura del proyecto KMM
Estructura del proyecto KMM
Vista de la estructura del proyecto KMM en Android Studio
Módulo compartido
módulo androidApp
módulo iOSApp
Estructura del proyecto KMM
Dependencias
Tu primer proyecto KMM
Pasos para crear un proyecto de KMM en Android Studio
Primera ejecución en iOS y Android
interface Platform {
val name: String
}
expect fun getPlatform(): Platform
class AndroidPlatform : Platform {
override val name: String = "Android ${android.os.Build.VERSION.SDK_INT}"
}
actual fun getPlatform(): Platform = AndroidPlatform()class IOSPlatform: Platform {
override val name: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion
}
actual fun getPlatform(): Platform = IOSPlatform()
sourceSets {
val commonMain by getting {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0")
}
}
...
}
import kotlinx.datetime.*
fun getToday(): String {
val today = Clock.System.todayIn(TimeZone.currentSystemDefault())
return today.dayOfMonth.toString() + " / " + today.monthNumber.toString() + " / " + today.year.toString()
}
fun greet(): String {
return "Hello, ${platform.name}!" + "\n\n" + "Today is ${getToday()}"
}
Ejecución de iOS y Android mostrando la fecha actual
val ktorVersion = "2.2.4"
sourceSets {
val commonMain by getting {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion")
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
}
}
val androidMain by getting {
dependencies {
implementation("io.ktor:ktor-client-android:$ktorVersion")
}
}
val iosMain by creating {
dependencies {
implementation("io.ktor:ktor-client-darwin:$ktorVersion")
}
...
}
...
}
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class RMCharacterList (
@SerialName("results")
val characters: List<RMCharacter>,
)
@Serializable
data class RMCharacter(
val name: String,
val species: String,
)
import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.request.get
import io.ktor.serialization.kotlinx.json.json
import kotlinx.serialization.json.Json
class Greeting {
private val platform: Platform = getPlatform()
private val httpClient = HttpClient {
install(ContentNegotiation) {
json(Json {
prettyPrint = true
isLenient = true
ignoreUnknownKeys = true
})
}
}
@Throws(Exception::class)
suspend fun greet(): String {
val response: RMCharacterList =
httpClient.get("https://rickandmortyapi.com/api/character").body()
val oneRMCharacter = response.characters.firstOrNull()
return "Hello, ${platform.name}!" +
"\n\n" +
"Today is ${getToday()}" +
"\n\n" +
"First character is ${oneRMCharacter?.name} and is ${oneRMCharacter?.species}"
}
}
import androidx.compose.runtime.*
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApplicationTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
var text by remember { mutableStateOf("Loading") }
LaunchedEffect(true) {
text = try {
Greeting().greet()
} catch (e: Exception) {
e.localizedMessage ?: "error"
}
}
GreetingView(text)
}
}
}
}
}
import SwiftUI
@main
struct iOSApp: App {
var body: some Scene {
WindowGroup {
ContentView(viewModel: ContentView.ViewModel())
}
}
}import SwiftUI
import shared
struct ContentView: View {
@ObservedObject private(set) var viewModel: ViewModel
var body: some View {
Text(viewModel.text)
}
}
extension ContentView {
class ViewModel: ObservableObject {
@Published var text = "Loading..."
init() {
// Data will be loaded here
Greeting().greet { greeting, error in
DispatchQueue.main.async {
if let greeting = greeting {
self.text = greeting
} else {
self.text = error?.localizedDescription ?? "error"
}
}
}
}
}
}
Resultado