App Group group.app.banyaro.ios verbindet App und Widget-Extension
(Entitlements in beiden Targets, CODE_SIGN_ENTITLEMENTS fürs Widget).
Home-Screen-Widget (D):
- BanYaroHomeWidget (klein + mittel): Tagesfoto, Hundename, nächster Termin.
- App schreibt beim Heim-Laden einen Snapshot (HomeWidgetData) in die App
Group und triggert WidgetCenter-Reload; Snapshot wird bei Logout/401 geleert.
Siri-/Kurzbefehl (E):
- StartWalkIntent „Gassi gehen" + AppShortcutsProvider (öffnet die App).
- WalkLauncher überbrückt Intent → UI: Flag in der App Group, beim Aktivwerden
eingelöst → Aufnehmen-Tab + Aufnahme-Start (TrackingView.startFresh).
- MainTabView mit Tab-Auswahl (Tags), BanYaroGoApp liest scenePhase.
App-Review-Fix (Guideline 2.1 WeatherKit):
- OneShotLocation: deterministisches async resolve() mit 10s-Timeout statt
onChange-Lauschen; WetterView lädt bei fehlendem Standort einen Berlin-Fallback
→ kein ewiges Hängen bei "Hole Standort…", WeatherKit ist immer sichtbar.
Offline-Lesen (SwiftData):
- CachedRoute/CachedDiaryEntry/CachedImage + CachedAsyncImage: Touren, Tagebuch
und Fotos werden cache-first geladen und sind offline verfügbar.
- Cache wird bei Logout/401 geleert (RootView), kein Durchschimmern fremder User.
Offline-Speichern (Outbox):
- PendingRoute/PendingRoutePhoto: Tour inkl. unterwegs hinzugefügter Fotos wird
offline lokal gesichert und automatisch hochgeladen (Touren-Tab + App-Start).
- Touren-Liste zeigt offline gesicherte Touren mit "wird hochgeladen"-Badge.
FinishWalkSheet:
- Dismiss-Schutz: Speichern-Dialog lässt sich nicht mehr wegwischen — eine
aufgezeichnete Tour geht nicht mehr durch Runterwischen verloren.
Wetter:
- Ortslabel (Reverse-Geocoding; Fallback "Berlin · Näherung").
- Saubere Offline-Meldung statt rohem networkError.
Aufräumen:
- Doppeltes "Gassi-Treffen" im Mehr-Tab entfernt.
- Veraltete Phase-1/2-Texte neu getextet.
- Tote DogsListView gelöscht (Hund-Wechsel läuft über den Heim-Picker).
- Statistik-Tab raus (für Go-Companion nicht relevant)
- Mehr-Duplikate raus: Meine Hunde, Tagebuch, Wetter, Erste Hilfe sitzen
bereits auf Heim als Quick-Action bzw. im Dog-Picker
- Im PWA ist 'Gassi' der social walks-Bereich (walks.py) und 'Stamm-Gassi-
Zeiten' nur ein Tab darin (Community-Pool, gassi_zeiten.py). Meine
Implementierung als 'tägliche Erinnerungen' war fachlich falsch:
+ Mehr-Eintrag heißt jetzt 'Stamm-Gassi-Zeiten'
+ ContentUnavailableView + Footer erklären die Community-Komponente
+ Pitch-Karte unterscheidet jetzt klar: 'Gassi-Treffen' (sich verabreden)
und 'Stamm-Gassi-Zeiten' (regelmäßige Runden + Pool)
+ 'Hunde-Orte' getrennt als eigener Pitch-Punkt
Tagebuch (Diary):
- DiaryEntry + DiaryMedia + DiaryCreateBody DTOs
- TagebuchView: Liste der Einträge für aktiven Hund mit Titel, Text,
Ortsname, Meilenstein-Stern, Foto-Strip
- AddDiaryEntrySheet: Titel/Text/Datum/Meilenstein/Ort/Tags +
PhotosPicker, nach POST /api/dogs/{id}/diary werden Fotos einzeln
via POST /api/dogs/{id}/diary/{entry_id}/media hochgeladen (mit
ImageResize.resizedJPEG)
Heim-Tab als neuer 1. Tab:
- DashboardSnapshot DTO für /api/dogs/{id}/welcome-dashboard
- ActiveDogStore (@Observable + UserDefaults("activeDogId")): hält
den aktiven Hund app-weit
- HeimView: tägliches Hintergrundfoto aus random_photo.url (rotiert
pro Tag, vom Backend gewählt), Gradient zur Lesbarkeit, Tagezeit-
Begrüßung mit User-Namen, Hund-Picker (Menu), Info-Karten für
letzten Eintrag/nächsten Termin/Gewicht/Eintragszahl,
Quick-Action-Buttons (Tagebuch, Wetter, Erste Hilfe)
Reorganisation:
- 5 Tabs: Heim, Touren, Aufnehmen, Statistik, Mehr
- Hunde-Liste wandert in Mehr → "Hund & Alltag"
- Tagebuch in Mehr → "Hund & Alltag" + erreichbar von Heim
D.10 401-Handling: APIError.unauthorized, NotificationCenter-Bridge,
AuthSession.logout() bei 401 → User landet wieder im Login
D.12 PWA-Deep-Links: Settings-Section mit Forum/Hunde/Walks/Settings
öffnet Safari per https://banyaro.app/#fragment
B.4 Auto-Pause: 2-min-Inaktivität → isAutoPaused, automatischer Resume bei
nächstem GPS-Update. Settings-Toggle, im UI eigenes Badge "Auto-Pause"
(grau vs. Pause orange).
C.7 Edit/Delete: RouteUpdateBody + APIClient.patch + APIClient.delete,
EditRouteSheet (Name/Beschreibung/Public), Menu in Toolbar (nur eigene
Touren), Alert für Delete.
C.9 Statistik-Tab: neuer Tab "Statistik" zwischen Hunde und Mehr. Filtert
/api/routes auf meine Touren, rechnet Woche/Monat/Allzeit (Distanz, Dauer,
Touren), Längste Tour, aktuelle Streak (Tage in Folge).
B.5 Walk-Review: Map-Header an die Spitze des FinishWalkSheet-Forms.
B.6 Geo-Fotos: CapturedPhoto (Data + GPSPoint?), PhotoLocation @Model in
SwiftData. Kamera während Walk taggt mit tracker.points.last. Nach Upload:
foto_url aus Response → PhotoLocation persistiert. MiniRouteMap rendert
Annotations mit Tap-Callback, PhotoViewerSheet zeigt Foto fullscreen.
C.8 Share PNG+GPX: RouteShareImage (MKMapSnapshotter + Polyline overlay +
SwiftUI ShareCard via ImageRenderer), GPXExporter (Tempfile mit XML),
ShareSheet (UIActivityViewController-Wrapper), Menu in Route-Toolbar.
D.11 Icon-Varianten: AppIcon-Dark (0.45 Brightness), AppIcon-Tinted
(Grayscale + Kontrastverstärkung), Contents.json mit appearance entries.
A.2 HealthKit: BanYaroGo.entitlements (com.apple.developer.healthkit),
NSHealthShare/UpdateUsageDescription. WalkHealthSync.shared mit
HKWorkoutBuilder (.walking) + HKWorkoutRouteBuilder, Timestamps gleichmäßig
über Walk-Dauer verteilt. Settings-Toggle mit Permission-Request.
Login liefert nur {token, name, is_premium}. Für Admin-/Founder-/Tier-Info
holen wir nach Login (und beim Erscheinen von MainTabView) /api/auth/me und
zeigen ein echtes Profil mit Avatar, Email, Rolle und nur dann Premium-Status,
wenn das relevant ist.