Commit graph

7 commits

Author SHA1 Message Date
b6a92c5811 Info.plist: ITSAppUsesNonExemptEncryption=false
App nutzt nur Standard-iOS-HTTPS/TLS — keine Custom-Crypto, keine
proprietären Verschlüsselungsalgorithmen. Mit diesem Flag entfällt
die Pflicht zur Compliance-Dokumentation bei App Store Connect.
2026-05-30 20:02:28 +02:00
7848817cbe GPX-Import via Teilen-Menü und 'Öffnen mit'
Andere Apps können jetzt GPX-Tracks zu Ban Yaro Go schicken (Komoot,
Outdooractive, GPSies, AllTrails, Files-App, Mail-Anhänge, AirDrop).

- Info.plist:
  - UTImportedTypeDeclarations: com.topografix.gpx (conforms to
    public.xml/data/content, ext gpx, MIME application/gpx+xml)
  - CFBundleDocumentTypes registriert die UTI als Viewer (LSHandlerRank
    Alternate, damit wir nicht die Default-App werden)
  - LSSupportsOpeningDocumentsInPlace=true
- Support/GPXParser.swift: schlanker XMLParser/SAX-Reader für
  <trkpt>/<wpt>/<rtept>, Track-Name aus <trk><name>, ele + ISO8601 time
- Views/GPXImportSheet.swift: Sheet mit Map(MapPolyline)+Start/Ziel-Pins,
  Distanz/Punkte/Dauer-Karte, zwei Aktionen:
    1. 'Als Tour übernehmen' — Name editierbar, Hunde-Picker (FlowDogs),
       öffentlich-Toggle → POST /api/routes
    2. 'Nur ansehen' — Startpunkt in Apple Maps
- BanYaroGoApp.swift: .onOpenURL prüft .gpx, security-scoped resource,
  parst und triggert das Sheet via TrackBox-Wrapper
2026-05-30 14:34:40 +02:00
3d229d42ce App-Store Vorbereitung: Privacy-Manifest + Konto-Löschen + Region de
- PrivacyInfo.xcprivacy: NSPrivacyTracking=false, deklariert gesammelte
  Daten (Email, Name, User-ID, präziser/grober Standort, Fotos, Fitness,
  Sonstiger Nutzerinhalt) — alle linked to user, kein Tracking, nur
  AppFunctionality. Required-Reason APIs: UserDefaults (CA92.1),
  FileTimestamp (C617.1), DiskSpace (E174.1), SystemBootTime (35F9.1).
- SettingsView: Section 'Konto löschen' mit zwei Bestätigungs-Alerts →
  DELETE /api/profile/account → automatischer logout. Erfüllt Apple-
  Pflicht seit iOS 16.4 (in-App-Löschung statt Web-Redirect).
- Info.plist: CFBundleDevelopmentRegion explizit 'de' (statt der
  $(DEVELOPMENT_LANGUAGE)-Variable, die sonst 'en' auflöst) → Store
  zeigt App als deutschsprachig an.
- NSHealthShareUsageDescription präziser formuliert (Reviewer-Hint).
2026-05-30 14:30:21 +02:00
500a645bfd Phase 4.A.1: Live Activity + Dynamic Island für laufende Gassi-Tour
Neues Widget-Extension-Target BanYaroGoWidgetExtension:
- Bundle-ID app.banyaro.ios.BanYaroGoWidget
- NSExtensionPointIdentifier = com.apple.widgetkit-extension
- Synced root group + explizite Info.plist + Embed-Phase in App-Target
- Cross-Membership der Shared/WalkActivityAttributes.swift in beiden Targets

Shared/WalkActivityAttributes.swift:
- ActivityAttributes mit startedAt (fix)
- ContentState mit distanceMeters, elapsedSeconds, pointCount, isPaused, isAutoPaused

BanYaroGoWidget/WalkLiveActivity.swift:
- Lock-Screen-View: Pfote-Icon + Status-Pille (Live/Pause/Auto-Pause) +
  Stats-Spalten (Distanz/Dauer/Punkte)
- Dynamic Island compact: Pfote leading, Distanz trailing
- Dynamic Island minimal: nur Pfote
- Dynamic Island expanded: Distanz/Dauer/Status mit Pfote zentriert

WalkActivityController:
- @MainActor Facade um ActivityKit
- start() prüft areActivitiesEnabled, killt orphaned current, request mit Initial-State
- update() async via Task
- end() mit dismissalPolicy.immediate

TrackingView:
- .onChange(of: tracker.isTracking) → Start/End
- persistTicker (5s) → update
- .onChange(of: tracker.isPaused/isAutoPaused) → sofort update für saubere UX

BanYaroGo-Info.plist: NSSupportsLiveActivities = true
2026-05-30 11:35:43 +02:00
c01e3d6be7 Phase 3.6: B+C+D komplett + HealthKit Sync
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.
2026-05-30 11:19:53 +02:00
5473bbf41f Phase 3.5: Pause/Resume, SwiftData-Persistenz, Kamera-Capture, Fotos zu bestehender Tour
LocationTracker:
- isPaused, pausedAt, accumulatedPausedSeconds
- pause()/resume()/restore() Methoden
- effectiveElapsedSeconds rechnet Pausen raus
- restore() für nach App-Crash: Offline-Lücke wird als Pause gezählt

ActiveWalk @Model (SwiftData):
- startedAt, lastUpdate, pausedAt, accumulatedPausedSeconds, pointsData
- Container in BanYaroGoApp registriert

TrackingView:
- Persistenz alle 5s via Timer
- confirmationDialog beim Erscheinen wenn ActiveWalk vorhanden:
  Fortsetzen / Jetzt speichern / Verwerfen
- Pause/Resume-Button + Stop-Button
- Floating Kamera-Button rechts unten
- Foto-Counter in der Stats-Karte
- Pause-Badge oben links bei Pause

CameraPicker: UIImagePickerController-Wrapper (Fallback auf Library im Simulator).

FinishWalkSheet: initialPhotos: [Data] für Kamera-Fotos während Tour.

RouteDetailView: PhotosPicker zum Hinzufügen von Fotos zu bestehender Tour,
sequentieller Upload mit Progress, Detail wird nach Upload refreshed.

NSCameraUsageDescription in BanYaroGo-Info.plist.
2026-05-30 10:52:15 +02:00
0b95e3e6d1 Phase 2: Live-GPS-Tracking + neues Icon
- BanYaroGo-Info.plist (explizit, statt INFOPLIST_KEY_*): UIBackgroundModes
  location, NSLocationWhenInUseUsageDescription,
  NSLocationAlwaysAndWhenInUseUsageDescription
- LocationTracker: CLLocationManager-Wrapper (@Observable @MainActor), Distanz
  via CLLocation.distance, Permission-Handling, Background-Updates
- RouteCreateBody + Encoder mit convertToSnakeCase für POST /api/routes
- TrackingView: Start-Hero-Screen + Live-Karte mit MapPolyline + Stats-Karte
- FinishWalkSheet: Name + Hunde-Multiselect + POST /api/routes
- MainTabView: neuer Aufnehmen-Tab zwischen Touren und Hunde
- AppIcon: neues Hund-mit-GPS-Pin (vom User bereitgestellt, weiße Ränder
  weggeschnitten + Ecken mit Hintergrundfarbe gefüllt)
2026-05-30 10:08:02 +02:00