123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- //
- // GiphyApiManager.swift
- // LiveLikeGiphyChallenge
- //
- // Created by Ljupco Nastevski on 30.1.22.
- //
- import Foundation
- enum GiphyApiError: Error {
- case canceledByUser
- case requestFailed
- case decodingFailed
- }
- fileprivate struct RequestParamKeys {
- static let ApiKey = "api_key"
- static let QueryKey = "q"
- static let OffsetKey = "offset"
- static let LimitKey = "limit"
- }
- fileprivate struct Versions {
- static let v1 = "/v1"
- }
- fileprivate struct Endpoints {
-
- static let Gifs = Versions.v1 + "/gifs"
-
- static let Trending = Gifs + "/trending"
- static let Search = Gifs + "/search"
-
- }
- class GiphyApiManager {
-
- static let shared = GiphyApiManager()
-
- private var baseUrl = URLComponents(string: Constants.GiphyBaseUrl)!
-
- private let session = URLSession(configuration: .ephemeral, delegate: nil, delegateQueue: nil)
-
- // Last searchable task
- private var lastSearchableTask: URLSessionDataTask?
-
- init() {
-
- // Default query items
- baseUrl.queryItems = [
- URLQueryItem(name: RequestParamKeys.ApiKey, value: Constants.GiphyApiKey),
- URLQueryItem(name: RequestParamKeys.LimitKey, value: String(Constants.GiphyPaginationLimit))
- ]
-
- }
-
- func cancelLastSearchableTask() {
- lastSearchableTask?.cancel()
- lastSearchableTask = nil
- }
-
- func cancelDataTaskForUrl(url: URL) {
-
- session.getAllTasks { tasks in
- tasks.filter { $0.state == .running }.filter { $0.originalRequest?.url == url}.first?.cancel()
- }
-
- }
-
- func getTrendingGifs(offset: Int, completion: @escaping (Result<GiphyListResponse, Error>) -> Void) {
-
- let offset = URLQueryItem(name: RequestParamKeys.OffsetKey, value: String(offset))
- self.lastSearchableTask = self.getCodable(endpoint: Endpoints.Trending, queries: [offset], completion: completion)
- }
-
- func getSearchGifs(offset: Int, query: String, completion: @escaping (Result<GiphyListResponse, Error>) -> Void) {
-
- let offset = URLQueryItem(name: RequestParamKeys.OffsetKey, value: String(offset))
- let query = URLQueryItem(name: RequestParamKeys.QueryKey, value: query)
- self.lastSearchableTask = self.getCodable(endpoint: Endpoints.Search, queries: [offset, query], completion: completion)
- }
-
- func getData(url: URL, completion: @escaping (Data?) -> Void) -> URLSessionDataTask {
- let task = session.dataTask(with: url) { data, _ , _ in
- completion(data)
- }
- task.resume()
- return task
- }
- private func getCodable<U:Codable>(endpoint: String, queries: [URLQueryItem]? = nil, completion: @escaping (Result<U, Error>) -> Void) -> URLSessionDataTask {
-
- var fullUrlComponent = self.baseUrl
-
- if let queries = queries {
- fullUrlComponent.queryItems?.append(contentsOf: queries)
- }
- fullUrlComponent.path = endpoint
-
-
- let task = session.dataTask(with: fullUrlComponent.url!) { d, _, e in
-
- guard let data = d else { completion(.failure(e!)); return }
-
- do {
- let decoded = try JSONDecoder().decode(U.self, from: data)
- completion(.success(decoded))
- } catch {
- completion(.failure(GiphyApiError.decodingFailed))
- }
-
- }
-
- task.resume()
- return task
- }
- }
|