Bug: ActiveDogStore cached dogs + activeDogId (UserDefaults). Beim Login mit einem neuen Account waren die Hunde des vorigen Users weiter zu sehen, weil HeimView nur loadDogs() ruft wenn dogs.isEmpty. Fix: - ActiveDogStore hat jetzt reset() (dogs=[], activeDogId=0, UserDefaults gelöscht). - ActiveDogStore hört auf .userDidLogout und auf .apiUnauthorized, beides löst reset() aus. - AuthSession.logout() postet jetzt .userDidLogout. - Nach Login holt HeimView's .task automatisch die neuen Hunde (dogs.isEmpty → loadDogs).
68 lines
2.2 KiB
Swift
68 lines
2.2 KiB
Swift
import Foundation
|
|
import Observation
|
|
|
|
/// Tracks the user's currently selected dog across the app. Picked once,
|
|
/// reused everywhere (Heim, Tagebuch, Statistik, …). Persisted in UserDefaults.
|
|
@Observable
|
|
@MainActor
|
|
final class ActiveDogStore {
|
|
var activeDogId: Int
|
|
var dogs: [Dog] = []
|
|
|
|
var activeDog: Dog? {
|
|
dogs.first(where: { $0.id == activeDogId }) ?? dogs.first
|
|
}
|
|
|
|
init() {
|
|
self.activeDogId = UserDefaults.standard.integer(forKey: "activeDogId")
|
|
// Auf User-Wechsel hören (Logout oder 401 = Token abgelaufen),
|
|
// damit nie die Hunde des vorigen Users durchschimmern.
|
|
NotificationCenter.default.addObserver(
|
|
forName: .userDidLogout,
|
|
object: nil,
|
|
queue: .main
|
|
) { [weak self] _ in
|
|
Task { @MainActor in self?.reset() }
|
|
}
|
|
NotificationCenter.default.addObserver(
|
|
forName: .apiUnauthorized,
|
|
object: nil,
|
|
queue: .main
|
|
) { [weak self] _ in
|
|
Task { @MainActor in self?.reset() }
|
|
}
|
|
}
|
|
|
|
func loadDogs() async {
|
|
do {
|
|
let fetched: [Dog] = try await APIClient.shared.get("/api/dogs")
|
|
self.dogs = fetched
|
|
if !fetched.contains(where: { $0.id == activeDogId }),
|
|
let first = fetched.first {
|
|
setActive(first.id)
|
|
}
|
|
} catch {
|
|
print("ActiveDogStore loadDogs failed: \(error)")
|
|
}
|
|
}
|
|
|
|
func setActive(_ dogId: Int) {
|
|
activeDogId = dogId
|
|
UserDefaults.standard.set(dogId, forKey: "activeDogId")
|
|
}
|
|
|
|
/// Komplett zurücksetzen — wird bei Logout / 401 aufgerufen, damit kein
|
|
/// Cache vom vorigen User durchschlägt. `loadDogs()` wird beim nächsten
|
|
/// Erscheinen einer Seite (`dogs.isEmpty`) automatisch wieder gefeuert.
|
|
func reset() {
|
|
dogs = []
|
|
activeDogId = 0
|
|
UserDefaults.standard.removeObject(forKey: "activeDogId")
|
|
}
|
|
}
|
|
|
|
extension Notification.Name {
|
|
/// Wird von `AuthSession.logout()` gepostet, damit abhängige Stores
|
|
/// (z.B. ActiveDogStore) ihren User-bezogenen Cache leeren.
|
|
static let userDidLogout = Notification.Name("BanYaroGo.userDidLogout")
|
|
}
|