1import Foundation23class FavoritesManager: ObservableObject {4 static let shared = FavoritesManager()56 @Published var favorites: [Wallpaper] = []7 8 9 10 @Published var persistenceError: String?1112 private let key = "favoriteWallpapers"13 private let defaults: UserDefaults14 private let encoder: JSONEncoder15 private let decoder: JSONDecoder1617 init(18 defaults: UserDefaults = .standard,19 encoder: JSONEncoder = JSONEncoder(),20 decoder: JSONDecoder = JSONDecoder()21 ) {22 self.defaults = defaults23 self.encoder = encoder24 self.decoder = decoder25 loadFavorites()26 }2728 func toggleFavorite(_ wallpaper: Wallpaper) {29 if let index = favorites.firstIndex(where: { $0.id == wallpaper.id }) {30 favorites.remove(at: index)31 } else {32 favorites.insert(wallpaper, at: 0)33 }34 saveFavorites()35 }3637 func isFavorite(_ wallpaper: Wallpaper) -> Bool {38 return favorites.contains(where: { $0.id == wallpaper.id })39 }4041 private func saveFavorites() {42 persist(currentFavorites())43 }4445 46 47 48 func persist(_ wallpapers: [Wallpaper]) {49 do {50 let data = try encoder.encode(wallpapers)51 defaults.set(data, forKey: key)52 persistenceError = nil53 } catch {54 persistenceError = "Failed to save favorites: \(error.localizedDescription)"55 }56 }5758 59 60 61 62 func decodeFavorites(from data: Data?) -> [Wallpaper]? {63 guard let data else {64 persistenceError = nil65 return nil66 }67 do {68 let decoded = try decoder.decode([Wallpaper].self, from: data)69 persistenceError = nil70 return decoded71 } catch {72 persistenceError = "Failed to load favorites: \(error.localizedDescription)"73 return nil74 }75 }7677 private func loadFavorites() {78 favorites = currentFavorites()79 }8081 private func currentFavorites() -> [Wallpaper] {82 let stored = defaults.data(forKey: key)83 return decodeFavorites(from: stored) ?? favorites84 }85}