banyaro-ios/BanYaroGo/API/DTOs.swift
rene 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

90 lines
1.9 KiB
Swift

import Foundation
// MARK: - Auth
struct LoginRequest: Encodable {
let email: String
let password: String
}
struct LoginResponse: Decodable {
let token: String
let name: String
let isPremium: Bool
}
struct UserProfile: Decodable {
let id: Int
let name: String
let email: String
let realName: String?
let rolle: String?
let isPremium: Bool?
// Backend bool-konvertiert nur is_premium; is_founder/is_partner kommen
// als SQLite-Int 0/1 zurück deshalb hier Int? statt Bool?.
let isFounder: Int?
let isPartner: Int?
let founderNumber: Int?
let subscriptionTier: String?
let avatarUrl: String?
let wohnort: String?
let bio: String?
var isFounderFlag: Bool { isFounder == 1 }
var isPartnerFlag: Bool { isPartner == 1 }
}
// MARK: - Dogs
struct Dog: Decodable, Identifiable {
let id: Int
let name: String
let rasse: String?
let fotoUrl: String?
let geburtstag: String?
}
// MARK: - Routes
struct GPSPoint: Codable, Hashable {
let lat: Double
let lon: Double
let alt: Double?
}
struct RouteListItem: Decodable, Identifiable {
let id: Int
let userId: Int
let name: String
let beschreibung: String?
let distanzKm: Double?
let dauerMin: Int?
let createdAt: String?
let previewTrack: [GPSPoint]
let fotoUrls: [String]?
let userName: String?
let isPublic: Bool?
}
struct RouteDetail: Decodable, Identifiable {
let id: Int
let userId: Int
let name: String
let beschreibung: String?
let distanzKm: Double?
let dauerMin: Int?
let gpsTrack: [GPSPoint]
let fotoUrls: [String]?
let createdAt: String?
let userName: String?
let dogIds: [Int]?
}
struct RouteCreateBody: Encodable {
let name: String
let gpsTrack: [GPSPoint]
let distanzKm: Double
let dauerMin: Int
let dogIds: [Int]
let isPublic: Bool
}