# SDK para Kotlin Multiplatform

URL: https://traqio.app/es/docs/sdks/kotlin-multiplatform
Last updated: 2026-10-14

Añade Traqio a una app Kotlin Multiplatform: una dependencia en commonMain, el contexto de Android, init desde el código compartido, ciclo de vida y URL.

`io.khufu.traqio:traqio-kmp` es el SDK de Traqio para Kotlin Multiplatform: el cliente (cola, envío por lotes, reintentos, deep links, consentimiento) vive en `commonMain`, y cada destino aporta sus piezas de plataforma: el **Install Referrer de Google Play** en Android y el registro en **SKAdNetwork** en iOS. Kotlin Multiplatform no tiene un ciclo de vida de app compartido, así que la app anfitriona informa de las vueltas al primer plano y reenvía las URL que la abren.

## Requisitos

- Kotlin 1.9 o posterior, con kotlinx-coroutines (lo incluye el SDK).
- Destinos: Android (API 21+), iosArm64 e iosSimulatorArm64.

## Configuración

### Añade la dependencia a commonMain

```kotlin
// shared/build.gradle.kts
kotlin {
    sourceSets {
        commonMain.dependencies {
            implementation("io.khufu.traqio:traqio-kmp:0.1.0")
        }
    }
}
```

Hasta que el artefacto esté en Maven Central, publica la build que te enviamos en tu repositorio Maven local (`mavenLocal()`) y conserva las mismas coordenadas.

### Adjunta el contexto de Android y luego inicializa

Android — Application:
```kotlin
import io.khufu.traqio.kmp.Traqio
import io.khufu.traqio.kmp.TraqioAndroid

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        TraqioAndroid.attach(this)   // FIRST: the SDK keeps its state in this app's SharedPreferences
        Traqio.init(sdkKey = "YOUR_SDK_KEY", endpoint = "https://api.traqio.app")
    }
}
```

iOS — init de App / didFinishLaunching:
```swift
// Swift, through your shared framework. Kotlin's `init` is `doInit` in Swift,
// and Kotlin default arguments are not visible there: pass every parameter.
Traqio.shared.doInit(
    sdkKey: "YOUR_SDK_KEY",
    endpoint: "https://api.traqio.app",
    userId: nil,
    deepLinking: true,
    consent: nil
)
```

### Informa de las aperturas de la app

```kotlin
// Android — e.g. a ProcessLifecycleOwner observer
override fun onStart(owner: LifecycleOwner) = Traqio.appOpened()

// iOS — sceneDidBecomeActive / applicationDidBecomeActive
Traqio.shared.appOpened()
```

Con un debounce de 30 minutos de sesión, así que es seguro llamarlo en cada reanudación. Sin él, parece que tus usuarios nunca vuelven, y la retención marca cero después del día 0.

### Reenvía las URL que abren la app

```kotlin
// In the activity that handles links — onCreate AND onNewIntent
TraqioAndroid.handleIntent(intent)

Traqio.onDeepLink { link -> link.deepLink?.let(router::navigate) }
```

```swift
// app/scene delegate, or SwiftUI .onOpenURL
Traqio.shared.handleUrlAsync(url: url.absoluteString, callback: nil)
```

## Eventos

```kotlin
Traqio.setUserId(user.id)              // same id as RevenueCat's app_user_id
Traqio.track("purchase", value = 9.99, currency = "EUR")
```

Los eventos se envían en cuanto se ponen en cola, en lotes de 20, y se reintentan con backoff exponencial hasta cinco minutos. Nombres: [Nombres de eventos](https://traqio.app/es/docs/concepts/events-and-revenue#names).

## Aún no está en este SDK

### iOS

Las instalaciones se registran en SKAdNetwork, pero no se define ningún valor de conversión ni se informa de ningún token de Apple Ads.

### Ambas plataformas

Sin reintento del Install Referrer, sin id de transacción en las compras, sin ingresos publicitarios de AdMob, sin borrado desde la app: usa [RevenueCat](https://traqio.app/es/docs/integrations/revenuecat) y el [borrado del lado del servidor](https://traqio.app/es/docs/concepts/privacy#erasure).

> **Pruebas hasta ahora** El código común y el de Android se compilan en CI y la lógica común tiene tests unitarios; el framework de iOS requiere una build en macOS que solo se ejecuta cuando se publica el paquete.

## Preguntas frecuentes

**¿Por qué hay que llamar a TraqioAndroid.attach antes de init?**
En Android el SDK guarda su estado (el indicador de instalación, la cola, el id del dispositivo) en las SharedPreferences de la app, lo que requiere un Context de Android que el código Kotlin compartido no tiene. attach le da el contexto de la aplicación. Llamar primero a init falla en el primer acceso al almacenamiento.

**¿Cómo llamo al SDK desde Swift?**
A través de tu framework compartido, como Traqio.shared. Kotlin/Native renombra en Swift una función llamada init a doInit, y los argumentos por defecto de Kotlin no son visibles desde Swift, así que todos los parámetros de doInit se pasan explícitamente.
