GifListPresenter.swift 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. //
  2. // GifListPresenter.swift
  3. // LiveLikeGiphyChallenge
  4. //
  5. // Created by Ljupco Nastevski on 30.1.22.
  6. //
  7. import Foundation
  8. /*!
  9. GifListPresenters delegate
  10. */
  11. protocol GifListPresenterDelegate: AnyObject {
  12. /// Called before making a call on an empty data
  13. func presenterWillStartLoadingForEmptyData()
  14. /// Called when inital data is loaded
  15. func presenterDidReceiveInitialData()
  16. /// Called when next page is loaded
  17. func presenterDidReceiveAdditionalData(at indexPaths: [IndexPath])
  18. }
  19. /*!
  20. Presenter that loads the trending page,
  21. if a search keyword is present, it uses that keyword to
  22. search the Giphy library
  23. */
  24. class GifListPresenter {
  25. weak var delegate: GifListPresenterDelegate?
  26. /*!
  27. Last searched term
  28. On search term change, reset the pagination
  29. */
  30. private var lastSearchedTerm: String = "" {
  31. willSet {
  32. if newValue != lastSearchedTerm {
  33. pagination = GifListPagination()
  34. }
  35. }
  36. }
  37. /*!
  38. Last pagination object
  39. */
  40. private var pagination: GifListPagination = GifListPagination()
  41. /*!
  42. Array of objects to be shown
  43. */
  44. var gifsList: [GifObject] = []
  45. /*!
  46. Only one pagination request should be active
  47. */
  48. var isLoadingNewPage = false
  49. /*!
  50. If a search query is present, search data is fetched.
  51. If there is no search query, trending data is fetched.
  52. */
  53. func getData(query: String) {
  54. self.lastSearchedTerm = query
  55. if lastSearchedTerm.isEmpty {
  56. self.fetchTrendingData()
  57. } else {
  58. self.fetchSearchData(query: query)
  59. }
  60. }
  61. /// Trending data call
  62. private func fetchTrendingData() {
  63. self.prepareForFetch()
  64. GiphyApiManager.shared.getTrendingGifs(offset: pagination.nextOffset) { [weak self] result in
  65. switch result {
  66. case .success(let listResponse):
  67. self?.didReceiveSuccessfulListResponse(listResponse: listResponse)
  68. case .failure(let error):
  69. print(error)
  70. }
  71. self?.isLoadingNewPage = false
  72. }
  73. }
  74. /// Search data called
  75. private func fetchSearchData(query: String) {
  76. self.prepareForFetch()
  77. GiphyApiManager.shared.getSearchGifs(offset: pagination.nextOffset, query: query) { [weak self] result in
  78. switch result {
  79. case .success(let listResponse):
  80. self?.didReceiveSuccessfulListResponse(listResponse: listResponse)
  81. case .failure(let error):
  82. print(error)
  83. }
  84. self?.isLoadingNewPage = false
  85. }
  86. }
  87. /// Prepares self before making a call
  88. private func prepareForFetch() {
  89. if self.gifsList.count == 0 {
  90. self.delegate?.presenterWillStartLoadingForEmptyData()
  91. }
  92. GiphyApiManager.shared.cancelLastSearchableTask()
  93. if pagination.count + pagination.offset != 0 {
  94. isLoadingNewPage = true
  95. }
  96. }
  97. private func didReceiveSuccessfulListResponse(listResponse: GiphyListResponse) {
  98. let offset = listResponse.pagination.offset
  99. if (offset == 0) {
  100. self.gifsList = listResponse.data
  101. self.delegate?.presenterDidReceiveInitialData()
  102. } else {
  103. let indexPaths = (offset..<(offset + listResponse.data.count)).map({IndexPath(row: $0, section: 0)})
  104. self.gifsList += listResponse.data
  105. self.delegate?.presenterDidReceiveAdditionalData(at: indexPaths)
  106. }
  107. self.pagination = listResponse.pagination
  108. }
  109. }