Click here for German / Hier klicken für Deutsch
Stormbreaker is not just another weather app. It is a showcase of modern Kotlin Multiplatform (KMP) development, pushing the boundaries of code sharing between Android, iOS, and Desktop (JVM).
Built with a strict Clean Architecture, it intentionally leans into "over-engineering" to demonstrate scalability, testability, and the separation of concerns using SOLID, KISS (ironically applied to individual modules), and DRY principles. It leverages Open-Meteo for weather data and Nominatim for geocoding. While favorite locations and user settings are persisted locally for quick access, forecast data is fetched live to ensure maximum accuracy.
Stormbreaker shares ~90% of its code across platforms, including UI, ViewModels, UseCases, and Data Layers. Platform-specific code is isolated to hardware interactions.
| Platform | Tech | Key Implementation Details |
|---|---|---|
| Android | Jetpack Compose | Uses WorkManager for reliable background updates. Custom BroadcastReceiver handling for alarms and boot events. |
| iOS | Compose Multiplatform | Implements native BGTaskScheduler for background fetches. Native CLLocationManager via Kotlin/Native interop. |
| Desktop (JVM) | Compose for Desktop | Window management, System Tray integration, and Swing-based interoperability where needed. |
| Forecast Overview | Hourly & Air Quality |
|---|---|
![]() |
![]() |
| 14-Day Forecast (Light/Dark Split) | Deep Metrics (Light/Dark Split) |
screen_recording_readme.mp4
- Smart Forecast System: Combines Open-Meteo weather data with reverse geocoding from Nominatim to provide precise, location-aware forecasts.
- Adaptive UI: Fully responsive layouts that adapt to mobile, tablet, and desktop window sizes using
ListDetailPaneScaffold.
- Advanced Metrics:
- Air Quality: Detailed graphs for PM10, PM2.5, NO2, Ozone, and more.
- Pollen Breakdown: Specific tracking for Alder, Birch, Grass, Mugwort, Olive, and Ragweed.
- Sun Curve: Custom Canvas-based visualization of sunrise/sunset and current sun position.
- Resilient Notifications:
- Android: Robust alarm scheduling handling
BOOT_COMPLETEDandSCHEDULE_EXACT_ALARM. - iOS: Local notifications triggered via background fetch.
- Desktop: System tray notifications.
- Android: Robust alarm scheduling handling
- Custom Graphing Engine: A bespoke, Bezier-curve based charting solution built entirely in Compose Canvas (no external charting libraries).
This project follows a strict Multi-Module Clean Architecture.
- Language: Kotlin 2.0+ (K2 Compiler enabled)
- UI Framework: Jetpack Compose & Compose Multiplatform
- Dependency Injection: Koin (utilizing highly granular module definitions).
- Network: Ktor with Content Negotiation.
- Database: Room Multiplatform (SQLite) for persisting user favorites and settings.
- Settings: DataStore Preferences for persistent user configuration.
- Async: Kotlin Coroutines & Flow.
- Date/Time:
kotlinx-datetime.
Why simple when you can make it robust?
- Granular Mappers: Every layer transition (DTO -> Domain -> UI) has dedicated mappers.
- Interactors: ViewModels do not talk to Repositories directly; they go through Interactors/UseCases to ensure business logic is decoupled.
- Convention Plugins: Custom Gradle logic defined in
build-logicto standardize module configuration.
A custom abstraction layer (AppPermissionService) handles permission logic across platforms:
- Android: Wraps
ActivityResultContractsand handles Rationale UI logic. - iOS: Interacts with
UNUserNotificationCenterandCLLocationManagerauthorization status. - JVM: Graceful fallbacks (permissions assumed granted or no-op).
The app combines two distinct APIs:
- Nominatim (OSM): For resolving coordinates to human-readable names.
- Open-Meteo: For raw weather data.
- Logic: The
MergeFavoriteForecastsUseCaseorchestrates these streams, handling bounding box calculations to map generic API results to user-saved favorites efficiently.
- Android: Implements a double-receiver pattern (
DailyForecastRebootReceiver&DailyForecastIntentReceiver) to ensure notifications survive reboots and are delivered exactly on time usingAlarmManager. - iOS: Uses Kotlin/Native interop to register background tasks that fetch data and trigger local notifications.
- Android Studio Koala or newer / IntelliJ IDEA 2024+
- JDK 21
- Xcode 15+ (for iOS target)
- Clone:
git clone https://github.com/Robert-P-M/Stormbreaker.git - Sync: Let Gradle sync the convention plugins and catalogs.
- Run:
- Select
composeAppconfiguration for Android. - Select
iosAppfor iOS Simulator. - Run
desktopRunGradle task for the JVM app.
- Select
Hier klicken für Englisch / Click here for English
Stormbreaker ist nicht nur eine weitere Wetter-App. Es ist eine Demonstration moderner Kotlin Multiplatform (KMP) Entwicklung, welche die Grenzen des Code-Sharings zwischen Android, iOS und Desktop (JVM) ausreizt.
Entwickelt mit einer strikten Clean Architecture, lehnt sich das Projekt bewusst in Richtung "Over-Engineering", um Skalierbarkeit, Testbarkeit und die Trennung von Zuständigkeiten mittels SOLID, KISS (ironisch auf Modulebene angewandt) und DRY Prinzipien zu demonstrieren. Es nutzt Open-Meteo für Wetterdaten und Nominatim für Geocoding. Während favorisierte Orte und Benutzereinstellungen lokal gespeichert werden, um schnellen Zugriff zu ermöglichen, werden Wetterdaten live abgerufen, um höchste Genauigkeit zu garantieren.
Stormbreaker teilt ~90% des Codes über alle Plattformen hinweg, einschließlich UI, ViewModels, UseCases und Data Layer. Plattformspezifischer Code beschränkt sich auf Hardware-Interaktionen.
| Plattform | Technologie | Wichtige Implementierungsdetails |
|---|---|---|
| Android | Jetpack Compose | Nutzt WorkManager für zuverlässige Hintergrund-Updates. Eigene BroadcastReceiver für Alarme und Boot-Events. |
| iOS | Compose Multiplatform | Implementiert nativen BGTaskScheduler für Hintergrundaktualisierungen. Nativer CLLocationManager via Kotlin/Native Interop. |
| Desktop (JVM) | Compose for Desktop | Fenstermanagement, System Tray Integration und Swing-basierte Interoperabilität wo nötig. |
| Vorhersage Übersicht | Stündliche Details & AQI |
|---|---|
![]() |
![]() |
| 14-Tage Vorschau (Light/Dark Split) | Detaillierte Metriken (Light/Dark Split) |
screen_recording_readme.mp4
- Intelligentes Vorhersagesystem: Kombiniert Open-Meteo Wetterdaten mit Reverse Geocoding von Nominatim für präzise, standortbezogene Vorhersagen.
- Adaptive UI: Vollständig responsive Layouts, die sich mittels
ListDetailPaneScaffoldan Smartphone-, Tablet- und Desktop-Fenster anpassen.
- Erweiterte Metriken:
- Luftqualität: Detaillierte Graphen für PM10, PM2.5, NO2, Ozon und mehr.
- Pollenflug: Spezifisches Tracking für Erle, Birke, Gräser, Beifuß, Olive und Ambrosia.
- Sonnenkurve: Eigene Canvas-basierte Visualisierung von Sonnenaufgang/-untergang und aktuellem Sonnenstand.
- Robuste Benachrichtigungen:
- Android: Zuverlässiges Alarm-Scheduling (behandelt
BOOT_COMPLETED&SCHEDULE_EXACT_ALARM). - iOS: Lokale Benachrichtigungen, ausgelöst durch Background Fetch.
- Desktop: System-Tray Benachrichtigungen.
- Android: Zuverlässiges Alarm-Scheduling (behandelt
- Eigene Graphing-Engine: Eine maßgeschneiderte, auf Bezier-Kurven basierende Charting-Lösung, komplett in Compose Canvas entwickelt (keine externen Libraries).
Dieses Projekt folgt einer strikten Multi-Module Clean Architecture.
- Sprache: Kotlin 2.0+ (K2 Compiler aktiviert)
- UI Framework: Jetpack Compose & Compose Multiplatform
- Dependency Injection: Koin (nutzt hoch-granulare Moduldefinitionen).
- Netzwerk: Ktor mit Content Negotiation.
- Datenbank: Room Multiplatform (SQLite) zur Speicherung von Favoriten und Einstellungen.
- Settings: DataStore Preferences für persistente Benutzerkonfiguration.
- Async: Kotlin Coroutines & Flow.
- Datum/Zeit:
kotlinx-datetime.
Warum einfach, wenn es auch robust geht?
- Granulare Mapper: Jeder Schichtübergang (DTO -> Domain -> UI) besitzt dedizierte Mapper.
- Interactors: ViewModels sprechen nicht direkt mit Repositories; sie nutzen Interactors/UseCases, um die Geschäftslogik zu entkoppeln.
- Convention Plugins: Eigene Gradle-Logik in
build-logiczur Standardisierung der Modulkonfiguration.
Eine eigene Abstraktionsschicht (AppPermissionService) steuert die Logik plattformübergreifend:
- Android: Kapselt
ActivityResultContractsund UI-Logik für Erklärungen (Rationale). - iOS: Interagiert mit
UNUserNotificationCenterundCLLocationManagerStatus. - JVM: Elegante Fallbacks (Berechtigungen werden als gewährt angenommen oder ignoriert).
Die App kombiniert zwei verschiedene APIs:
- Nominatim (OSM): Zur Auflösung von Koordinaten in lesbare Namen.
- Open-Meteo: Für Roh-Wetterdaten.
- Logik: Der
MergeFavoriteForecastsUseCaseorchestriert diese Datenströme und behandelt Bounding-Box-Berechnungen, um generische API-Ergebnisse effizient den gespeicherten Favoriten zuzuordnen.
- Android: Implementiert ein Double-Receiver-Pattern (
DailyForecastRebootReceiver&DailyForecastIntentReceiver), um sicherzustellen, dass Benachrichtigungen Neustarts überleben und mittelsAlarmManagerpünktlich zugestellt werden. - iOS: Nutzt Kotlin/Native Interop, um Background Tasks zu registrieren, die Daten abrufen und lokale Benachrichtigungen auslösen.
- Android Studio Koala oder neuer / IntelliJ IDEA 2024+
- JDK 21
- Xcode 15+ (für iOS Target)
- Klonen:
git clone https://github.com/Robert-P-M/Stormbreaker.git - Sync: Lass Gradle die Plugins und Kataloge synchronisieren.
- Starten:
- Wähle die
composeAppKonfiguration für Android. - Wähle
iosAppfür den iOS Simulator. - Führe den
desktopRunGradle Task für die JVM App aus.
- Wähle die
MIT License. See LICENSE for details.
Crafted with ❤️ and too much coffee in Tyrol, Austria.



