WallhavenAPI.swift

2.6 KB · raw

1import Foundation23enum WallhavenError: Error {4    case invalidURL5    case networkError(Error)6    case decodingError(Error)7    case noData8    case apiError(String)9}1011class WallhavenAPI {12    private let session: URLSession13    14    init(session: URLSession = .shared) {15        self.session = session16    }17    18    func fetchRandomWallpapers(limit: Int = 1) async throws -> [Wallpaper] {19        let queryItems = [20            URLQueryItem(name: "sorting", value: "random"),21            URLQueryItem(name: "limit", value: String(limit))22        ]23        let (data, _) = try await performSearch(queryItems: queryItems)24        return data25    }26    27    func searchWallpapers(28        query: String,29        categories: String = "111",30        purity: String = "100",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: "date_added"),41            URLQueryItem(name: "limit", value: String(limit)),42            URLQueryItem(name: "page", value: String(page))43        ]44        45        if !resolutions.isEmpty {46            queryItems.append(URLQueryItem(name: "resolutions", value: resolutions.joined(separator: ",")))47        }48        49        if !ratios.isEmpty {50            queryItems.append(URLQueryItem(name: "ratios", value: ratios.joined(separator: ",")))51        }52        53        return try await performSearch(queryItems: queryItems)54    }55    56    private func performSearch(queryItems: [URLQueryItem]) async throws -> ([Wallpaper], Meta?) {57        var urlComponents = URLComponents(url: Configuration.baseURL.appendingPathComponent("search"), resolvingAgainstBaseURL: true)!58        urlComponents.queryItems = queryItems59        60        guard let url = urlComponents.url else {61            throw WallhavenError.invalidURL62        }63        64        let (data, response) = try await session.data(from: url)65        66        guard let httpResponse = response as? HTTPURLResponse, 67              (200...299).contains(httpResponse.statusCode) else {68            throw WallhavenError.apiError("Server returned an error")69        }70        71        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}