iOS · AndroidMOBILE APP

EVChargeProKMP

Write the charger-scoring algorithm once. Ship it to Android and iOS simultaneously.

Kotlin MultiplatformCompose MultiplatformMapbox SDKiOSAndroid
EVChargeProKMP

Kotlin Multiplatform · Compose Multiplatform · Mapbox SDK · iOS

0
Platforms from 1 codebase
0
SmartPick categories
0
Filter dimensions
0
Map bounds debounce

OVERVIEW

|

EV charging apps are typically built twice, once for Android and once for iOS, with business logic that drifts between platforms over time. Bugs fixed on one platform silently persist on the other. Filter rules, scoring algorithms, and availability calculations end up subtly different across codebases.

|

A Kotlin Multiplatform project where all ViewModels, repositories, data models, and algorithms live in commonMain and compile to both JVM (Android) and ARM (iOS). Compose Multiplatform renders the UI from the same composable tree on both platforms. Mapbox provides maps and geocoding across both targets via a KMP-compatible SDK.

|

A single codebase powers Android and iOS with identical business logic, changes to the SmartPick scoring algorithm, filter pipeline, or availability model propagate to both platforms simultaneously with no dual-PR overhead.

KEY FEATURES

Shared Business Logic

ViewModels, repositories, scoring algorithms, and filter pipelines are written once in commonMain Kotlin and compiled to both platforms. The SmartPick algorithm runs identically on Android and iOS, no synchronisation bugs possible.

TECH STACK

Tap to see the reasoning

BUILD TIMELINE

Phase 01

KMP Architecture

Set up the Kotlin Multiplatform project with commonMain, androidMain, and iosMain source sets. Defined @Serializable data models (ChargerStation, Connector, FilterState, GeocodeResult) and the repository interfaces.

CHALLENGES & SOLUTIONS

Mapbox's Maven repository requires HTTP Basic authentication with a private download token. Configuring this in settings.gradle.kts to apply to all target dependency resolution (not just Android) required explicit repository scoping, the default Gradle configuration only applied the credentials to the Android target.

The Mapbox Geocoding SDK uses callback-based APIs on both platforms that don't directly expose Kotlin coroutines. A thin expect/actual bridge in androidMain and iosMain wraps the SDK callbacks in suspendCancellableCoroutine, keeping the ExploreViewModel's search logic purely coroutine-based in commonMain.

LET'S BUILD SOMETHING TOGETHER

I'm always open to discussing new projects, partnerships, or just a good idea.