Case study · Kotlin Multiplatform / Jetpack Compose

ParkSpot

App Kotlin Multiplatform para guardar la ubicacion del auto, gestionar historial y controlar tickets de parking con timer y notificaciones.

Kotlin MultiplatformCompose MultiplatformKoinRoomDataStoreKtorMapbox SDKForeground ServiceNotificationsiOS
Visitar proyecto ↗
Screenshot_20260314-193049.pngScreenshot_20260314-193053.pngScreenshot_20260314-193055.pngScreenshot_20260314-193157.pngScreenshot_20260314-193238.pngScreenshot_20260314-193241.png

App Kotlin Multiplatform para guardar la ubicacion del auto, gestionar historial y controlar tickets de parking con timer y notificaciones.

ParkSpot es una aplicacion Kotlin Multiplatform enfocada en resolver un problema diario: recordar donde quedo estacionado tu auto y controlar el tiempo del ticket de parking sin fricciones.

Lo que hace el proyecto

- 🧭 Onboarding inicial para configurar el flujo de uso.
• 📍 Seleccion y guardado de ubicaciones de estacionamiento.
• 🗂️ Historial de lugares guardados con pantalla de detalle por ticket.
• 🗺️ Mapa en Android con Mapbox para crear spots de forma visual.
• 🍎 Soporte iOS para la app compartida (mapa nativo iOS en estado base).
• ⏱️ Timer de ticket de parking con notificaciones inteligentes.

Timer y notificaciones de parking

#### Flujo funcional

1. El usuario crea un spot desde la pantalla de mapa (Car) y puede definir `parkUntil`. 2. Si hay `parkUntil`, se solicita permiso de notificaciones en Android (`POST_NOTIFICATIONS`). 3. Al guardar, se inicia un timer nativo sin depender de abrir ParkingDetail. 4. El timer sigue activo con Foreground Service mientras haya tiempo restante.

#### Android

- Implementacion nativa en `composeApp/src/androidMain/.../ParkingForegroundService.kt`.
• Notificacion persistente con cronometro (`setUsesChronometer(true)`).
• Deep link al ticket al tocar la notificacion.
• Alertas adicionales automaticas al 50%, 10% y fin del ticket.
• Servicio desacoplado de la pantalla de detalle para mantener el timer fuera de UI.

#### iOS

- Implementacion base en `composeApp/src/iosMain/.../ParkingNotificationService.ios.kt`.
• Estructura minima de notificaciones con `UNUserNotificationCenter`.
• Aun no replica la experiencia foreground en vivo de Android.

Stack tecnico

- ⚙️ Kotlin Multiplatform + Compose Multiplatform.
• 🧩 Koin para inyeccion de dependencias.
• 💾 Room y DataStore para persistencia local.
• 🌐 Ktor para networking.
• 🗺️ Mapbox (maps-compose) en Android.

Arquitectura y estructura

El proyecto esta organizado por feature y capas:

- `feature/*/data`: repositorios e implementaciones de data sources.
• `feature/*/domain`: modelos y casos de uso.
• `feature/*/presentation`: ViewModel y UI en Compose.
• DI centralizada en `composeApp/src/commonMain/kotlin/org/christophertwo/car/di/FeaturesModules.kt`.

Notas de configuracion

- El token de Mapbox se inyecta en build time desde `androidapp/build.gradle.kts` como `mapbox_access_token`.
• Configuracion recomendada local: `local.properties` con `MAPBOX_ACCESS_TOKEN=pk.your_token_here`.
• Tambien existe fallback con `MAPBOX_SECRET_TOKEN`.
• Si el usuario deniega notificaciones en Android, el timer visual sigue funcionando en app, pero las notificaciones pueden no mostrarse.

ParkSpot prioriza una experiencia util en el mundo real: guardar rapido, consultar facil y no perder el control del tiempo de estacionamiento.

← Volver al archivo