1import Foundation23enum WallhavenError: Error {4 case invalidURL5 case networkError(Error)6 case decodingError(Error)7 case noData8 case apiError(String)9}10111213enum WallhavenSorting: String {14 case dateAdded = "date_added"15 case toplist16 case random17}1819class WallhavenAPI {20 private let session: URLSession2122 init(session: URLSession = .shared) {23 self.session = session24 }2526 func searchWallpapers(27 query: String,28 categories: String = "111",29 purity: String = "100",30 sorting: WallhavenSorting = .dateAdded,31 resolutions: [String] = [],32 ratios: [String] = [],33 limit: Int = 24,34 page: Int = 135 ) async throws -> ([Wallpaper], Meta?) {36 var queryItems = [37 URLQueryItem(name: "q", value: query),38 URLQueryItem(name: "categories", value: categories),39 URLQueryItem(name: "purity", value: purity),40 URLQueryItem(name: "sorting", value: sorting.rawValue),41 URLQueryItem(name: "limit", value: String(limit)),42 URLQueryItem(name: "page", value: String(page))43 ]4445 if !resolutions.isEmpty {46 queryItems.append(URLQueryItem(name: "resolutions", value: resolutions.joined(separator: ",")))47 }4849 if !ratios.isEmpty {50 queryItems.append(URLQueryItem(name: "ratios", value: ratios.joined(separator: ",")))51 }5253 return try await performSearch(queryItems: queryItems)54 }5556 private func performSearch(queryItems: [URLQueryItem]) async throws -> ([Wallpaper], Meta?) {57 var urlComponents = URLComponents(url: Configuration.baseURL.appendingPathComponent("search"), resolvingAgainstBaseURL: true)!58 urlComponents.queryItems = queryItems5960 guard let url = urlComponents.url else {61 throw WallhavenError.invalidURL62 }6364 let (data, response) = try await session.data(from: url)6566 guard let httpResponse = response as? HTTPURLResponse,67 (200...299).contains(httpResponse.statusCode) else {68 throw WallhavenError.apiError("Server returned an error")69 }7071 do {72 let decodedResponse = try JSONDecoder().decode(WallhavenResponse.self, from: data)73 return (decodedResponse.data, decodedResponse.meta)74 } catch {75 throw WallhavenError.decodingError(error)76 }77 }78}