From fb367e1e940fa4977110a9f2269bf09a7c6cceab Mon Sep 17 00:00:00 2001 From: Brent Mifsud Date: Sat, 1 Jun 2019 17:55:48 -0400 Subject: [PATCH] fix issue #13 - lists wont show more than 20 movies - https://github.com/udacity/ios-nd-networking/issues/13 --- .../Controller/SearchViewController.swift | 34 ++++++++++++++++--- .../Model/TMDB Client/TMDBClient.swift | 12 +++---- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/TheMovieManager/Controller/SearchViewController.swift b/TheMovieManager/Controller/SearchViewController.swift index 390a5bb..b4def9f 100644 --- a/TheMovieManager/Controller/SearchViewController.swift +++ b/TheMovieManager/Controller/SearchViewController.swift @@ -18,6 +18,10 @@ class SearchViewController: UIViewController { var selectedIndex = 0 var currentSearchTask: URLSessionTask? + + var currentPageNumber: Int = 0 + + var maxPageCount: Int = 0 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "showDetail" { @@ -32,10 +36,13 @@ extension SearchViewController: UISearchBarDelegate { func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { currentSearchTask?.cancel() - currentSearchTask = TMDBClient.searchForMovie(query: searchText) { (movies, error) in - if let movies = movies { - self.movies = movies - self.tableView.reloadData() + currentSearchTask = TMDBClient.searchForMovie(query: searchText) { (movieResults, error) in + if let movieResults = movieResults { + weak var searchVC = self + searchVC?.movies = movieResults.results + searchVC?.currentPageNumber = movieResults.page + searchVC?.maxPageCount = movieResults.totalPages + searchVC?.tableView.reloadData() } } } @@ -93,5 +100,24 @@ extension SearchViewController: UITableViewDataSource, UITableViewDelegate { performSegue(withIdentifier: "showDetail", sender: nil) tableView.deselectRow(at: indexPath, animated: true) } + + func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { + guard currentPageNumber > 0 else { return } + guard maxPageCount > 0 else { return } + guard currentPageNumber + 1 <= maxPageCount else { return } + guard indexPath.row == movies.count-1 else { return } + + if let query = searchBar.text { + TMDBClient.searchForMovie(query: query, page: currentPageNumber + 1) { (movieResults, error) in + if let movieResults = movieResults { + weak var searchVC = self + searchVC?.movies.append(contentsOf: movieResults.results) + searchVC?.tableView.reloadData() + searchVC?.currentPageNumber = movieResults.page + searchVC?.maxPageCount = movieResults.totalPages + } + } + } + } } diff --git a/TheMovieManager/Model/TMDB Client/TMDBClient.swift b/TheMovieManager/Model/TMDB Client/TMDBClient.swift index 9a265be..a361e38 100644 --- a/TheMovieManager/Model/TMDB Client/TMDBClient.swift +++ b/TheMovieManager/Model/TMDB Client/TMDBClient.swift @@ -36,7 +36,7 @@ class TMDBClient { case markWatchlist case markFavorite case getPosterImage(String) - case search(String) + case search(String, Int) var stringValue: String { switch self { @@ -50,7 +50,7 @@ class TMDBClient { case .markWatchlist: return Endpoints.base + "/account/\(Auth.accountId)/watchlist" + Endpoints.apiKeyParam + "&session_id=\(Auth.sessionId)" case .markFavorite: return Endpoints.base + "/account/\(Auth.accountId)/favorite" + Endpoints.apiKeyParam + "&session_id=\(Auth.sessionId)" case .getPosterImage(let posterPath): return Endpoints.basePoster + posterPath - case .search(let movieQuery): return Endpoints.base + "/search/movie" + Endpoints.apiKeyParam + "&query=\(movieQuery.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "")" + case .search(let movieQuery, let page): return Endpoints.base + "/search/movie" + Endpoints.apiKeyParam + "&query=\(movieQuery.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "")" + "&page=\(page)" } } @@ -136,12 +136,12 @@ class TMDBClient { } } - class func searchForMovie(query: String, completion: @escaping ([Movie]?, Error?) -> Void) -> URLSessionTask { - let task = taskForGetRequest(url: Endpoints.search(query).url, responseType: MovieResults.self) { (response, error) in + @discardableResult class func searchForMovie(query: String, page: Int = 1, completion: @escaping (MovieResults?, Error?) -> Void) -> URLSessionTask { + let task = taskForGetRequest(url: Endpoints.search(query, page).url, responseType: MovieResults.self) { (response, error) in if let response = response { - completion(response.results, nil) + completion(response, nil) } else { - completion([], error) + completion(nil, error) } } return task