// // GifListPresenter.swift import Foundation /*! GifListPresenters delegate */ protocol GifListPresenterDelegate: AnyObject { /// Called before making a call on an empty data func presenterWillStartLoadingForEmptyData() /// Called when inital data is loaded func presenterDidReceiveInitialData() /// Called when next page is loaded func presenterDidReceiveAdditionalData(at indexPaths: [IndexPath]) } /*! Presenter that loads the trending page, if a search keyword is present, it uses that keyword to search the Giphy library */ class GifListPresenter { weak var delegate: GifListPresenterDelegate? /*! Last searched term On search term change, reset the pagination */ private var lastSearchedTerm: String = "" { willSet { if newValue != lastSearchedTerm { pagination = GifListPagination() } } } /*! Last pagination object */ private var pagination: GifListPagination = GifListPagination() /*! Array of objects to be shown */ var gifsList: [GifObject] = [] /*! Only one pagination request should be active */ var isLoadingNewPage = false /*! If a search query is present, search data is fetched. If there is no search query, trending data is fetched. */ func getData(query: String) { self.lastSearchedTerm = query if lastSearchedTerm.isEmpty { self.fetchTrendingData() } else { self.fetchSearchData(query: query) } } /// Trending data call private func fetchTrendingData() { self.prepareForFetch() GiphyApiManager.shared.getTrendingGifs(offset: pagination.nextOffset) { [weak self] result in switch result { case .success(let listResponse): self?.didReceiveSuccessfulListResponse(listResponse: listResponse) case .failure(let error): print(error) } self?.isLoadingNewPage = false } } /// Search data called private func fetchSearchData(query: String) { self.prepareForFetch() GiphyApiManager.shared.getSearchGifs(offset: pagination.nextOffset, query: query) { [weak self] result in switch result { case .success(let listResponse): self?.didReceiveSuccessfulListResponse(listResponse: listResponse) case .failure(let error): print(error) } self?.isLoadingNewPage = false } } /// Prepares self before making a call private func prepareForFetch() { if self.gifsList.count == 0 { self.delegate?.presenterWillStartLoadingForEmptyData() } GiphyApiManager.shared.cancelLastSearchableTask() if pagination.count + pagination.offset != 0 { isLoadingNewPage = true } } private func didReceiveSuccessfulListResponse(listResponse: GiphyListResponse) { let offset = listResponse.pagination.offset if (offset == 0) { self.gifsList = listResponse.data self.delegate?.presenterDidReceiveInitialData() } else { let indexPaths = (offset..<(offset + listResponse.data.count)).map({IndexPath(row: $0, section: 0)}) self.gifsList += listResponse.data self.delegate?.presenterDidReceiveAdditionalData(at: indexPaths) } self.pagination = listResponse.pagination } }