Kalorien-App ohne Account: Lokales Tracking mit SwiftUI
17. März 2026 · 7 Min. Lesezeit
Die meisten Kalorien-Apps wollen dein Gewicht, deine E-Mail-Adresse und am liebsten auch deine Kreditkarte. PlainTrack macht es anders: Barcode scannen, Menge eingeben, fertig. Kein Account, kein Cloud-Sync, kein Tracking. Alle Daten bleiben lokal auf dem iPhone.
Design-Philosophie: Bewusster Minimalismus
Die Design-Philosophie definiert explizit, was PlainTrack nicht ist:
- ❌ Keine Social Features / Community
- ❌ Keine Gamification / Challenges / Streaks
- ❌ Keine Rezepte / Diätpläne / Ernährungsberatung
- ❌ Kein Premium / Subscription / In-App-Purchases
- ❌ Kein Cloud-Sync / Account-System
- ❌ Keine Werbung / Tracking / Analytics
Was bleibt? Eine App, die exakt eine Sache gut macht: Kalorien zählen.
Kern-Use-Case: 2 Taps bis zum Eintrag
Das Ziel: Maximal 2 Taps vom Öffnen bis zum gespeicherten Eintrag. Der Workflow:
- Barcode scannen (AVFoundation / VisionKit)
- Produkt aus OpenFoodFacts finden
- Menge eingeben (Gramm, ml, Stück)
- Speichern
Alternativ können generische Lebensmittel wie „1 Apfel" oder „200g Reis" schnell manuell hinzugefügt werden.
Tagesübersicht: Die Energiebilanz
Die Hauptansicht zeigt die tägliche Energiebilanz auf einen Blick:
- Kalorien gegessen – Summe aller Einträge des Tages
- Grundumsatz (BMR) – Berechnet nach Mifflin-St Jeor (Geschlecht, Alter, Größe, Gewicht)
- Aktivitätsumsatz – Aus HealthKit importierte Bewegungskalorien
- Trainings – Einzelne Trainings-Sessions aus HealthKit
- Gesamtumsatz – BMR + Aktivität + Training
- Bilanz – Gegessen minus Gesamtumsatz = Defizit oder Überschuss
HealthKit-Integration
PlainTrack liest den aktiven Energieverbrauch und Workout-Daten aus HealthKit. HealthKit wird bewusst nur lesend genutzt – PlainTrack schreibt keine Daten zurück. So bleibt die App maximal uninvasiv.
Lokale Persistenz mit SwiftData
Alle Daten werden in SwiftData gespeichert – Apples modernes Persistence-Framework, das Core Data ablöst. SwiftData nutzt @Model-Macros und @Query für reaktive UI-Updates:
@Model final class FoodEntry { var name: String var calories: Double var amount: Double var unit: FoodUnit // .gram, .ml, .piece var date: Date var barcode: String? } // In der View: automatisch reaktiv @Query( filter: #Predicate { $0.date >= startOfDay }, sort: \.date ) var todayEntries: [FoodEntry]
Tech Stack
- UI: SwiftUI (MVVM)
- Persistenz: SwiftData
- Barcode: AVFoundation / VisionKit (native Kamera)
- Gesundheitsdaten: HealthKit (nur lesend)
- Netzwerk: URLSession (kein Alamofire)
- Sprache: Deutsch
- Maßeinheiten: Gramm, Milliliter, Stück
- Third-Party: Keine, wenn nicht zwingend nötig
→ Projekt ansehen: PlainTrack – Projektdetails