Ban Yaro Go — Phase 1 Foundation
SwiftUI/SwiftData iOS-Client, redet mit https://banyaro.app FastAPI-Backend. Bundle-ID app.banyaro.ios, Xcode-26-Projekt mit synchronisierten Ordnern. Drin: - APIClient (URLSession + Bearer + convertFromSnakeCase Decoder) - KeychainStore + AuthSession (@Observable) für persistenten Login - LoginView, MainTabView, SettingsView (mit Logout) - RoutesListView + RouteDetailView mit MapKit-Polyline aus preview_track - DogsListView mit Foto-Avatar - App-Icon (Pfote auf Banyaro-Amber)
This commit is contained in:
commit
81681130e6
20 changed files with 1129 additions and 0 deletions
50
BanYaroGo/Auth/AuthSession.swift
Normal file
50
BanYaroGo/Auth/AuthSession.swift
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import Foundation
|
||||
import Observation
|
||||
|
||||
@Observable
|
||||
@MainActor
|
||||
final class AuthSession {
|
||||
var token: String?
|
||||
var userName: String?
|
||||
var isPremium: Bool = false
|
||||
var isLoggingIn: Bool = false
|
||||
var errorMessage: String?
|
||||
|
||||
private let tokenKey = "by_token"
|
||||
|
||||
init() {
|
||||
if let savedToken = KeychainStore.read(tokenKey) {
|
||||
token = savedToken
|
||||
APIClient.shared.token = savedToken
|
||||
}
|
||||
}
|
||||
|
||||
var isLoggedIn: Bool { token != nil }
|
||||
|
||||
func login(email: String, password: String) async {
|
||||
isLoggingIn = true
|
||||
errorMessage = nil
|
||||
defer { isLoggingIn = false }
|
||||
do {
|
||||
let response: LoginResponse = try await APIClient.shared.post(
|
||||
"/api/auth/login",
|
||||
body: LoginRequest(email: email, password: password)
|
||||
)
|
||||
KeychainStore.save(response.token, for: tokenKey)
|
||||
APIClient.shared.token = response.token
|
||||
self.token = response.token
|
||||
self.userName = response.name
|
||||
self.isPremium = response.isPremium
|
||||
} catch {
|
||||
self.errorMessage = error.localizedDescription
|
||||
}
|
||||
}
|
||||
|
||||
func logout() {
|
||||
KeychainStore.delete(tokenKey)
|
||||
APIClient.shared.token = nil
|
||||
token = nil
|
||||
userName = nil
|
||||
isPremium = false
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue