Skip to content

Commit e28afb3

Browse files
authored
FEATURE: Added Now Playing Movies and Top Rated Movies and Upcoming Movies (#27)
1 parent 48a4fd8 commit e28afb3

File tree

6 files changed

+509
-2
lines changed

6 files changed

+509
-2
lines changed

Sources/TMDb/Services/Movies/MovieService.swift

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,18 @@ public protocol MovieService {
9494
func fetchSimilar(toMovie movieID: Movie.ID, page: Int?,
9595
completion: @escaping (_ result: Result<MoviePageableList, TMDbError>) -> Void)
9696

97+
/// Publishes a list of currently playing movies.
98+
///
99+
/// - Note: [TMDb API - Movie: Now Playing](https://developers.themoviedb.org/3/movies/get-now-playing)
100+
///
101+
/// - precondition: `page` can be between `1` and `1000`.
102+
///
103+
/// - Parameters:
104+
/// - page: The page of results to return.
105+
/// - completion: Completion handler.
106+
/// - result: Current popular movies as a pageable list.
107+
func fetchNowPlaying(page: Int?, completion: @escaping (_ result: Result<MoviePageableList, TMDbError>) -> Void)
108+
97109
/// Publishes a list of current popular movies.
98110
///
99111
/// - Note: [TMDb API - Movie: Popular](https://developers.themoviedb.org/3/movies/get-popular-movies)
@@ -105,6 +117,30 @@ public protocol MovieService {
105117
/// - completion: Completion handler.
106118
/// - result: Current popular movies as a pageable list.
107119
func fetchPopular(page: Int?, completion: @escaping (_ result: Result<MoviePageableList, TMDbError>) -> Void)
120+
121+
/// Publishes a list of top rated movies.
122+
///
123+
/// - Note: [TMDb API - Movie: Top Rated](https://developers.themoviedb.org/3/movies/get-top-rated-movies)
124+
///
125+
/// - precondition: `page` can be between `1` and `1000`.
126+
///
127+
/// - Parameters:
128+
/// - page: The page of results to return.
129+
/// - completion: Completion handler.
130+
/// - result: Current popular movies as a pageable list.
131+
func fetchTopRated(page: Int?, completion: @escaping (_ result: Result<MoviePageableList, TMDbError>) -> Void)
132+
133+
/// Publishes a list of upcoming movies.
134+
///
135+
/// - Note: [TMDb API - Movie: Upcoming](https://developers.themoviedb.org/3/movies/get-upcoming)
136+
///
137+
/// - precondition: `page` can be between `1` and `1000`.
138+
///
139+
/// - Parameters:
140+
/// - page: The page of results to return.
141+
/// - completion: Completion handler.
142+
/// - result: Current popular movies as a pageable list.
143+
func fetchUpcoming(page: Int?, completion: @escaping (_ result: Result<MoviePageableList, TMDbError>) -> Void)
108144

109145
#if canImport(Combine)
110146
/// Publishes the primary information about a movie.
@@ -195,6 +231,19 @@ public protocol MovieService {
195231
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
196232
func similarPublisher(toMovie movieID: Movie.ID, page: Int?) -> AnyPublisher<MoviePageableList, TMDbError>
197233

234+
/// Publishes a list of currently playing movies.
235+
///
236+
/// - Note: [TMDb API - Movie: Now Playing](https://developers.themoviedb.org/3/movies/get-now-playing)
237+
///
238+
/// - precondition: `page` can be between `1` and `1000`.
239+
///
240+
/// - Parameters:
241+
/// - page: The page of results to return.
242+
///
243+
/// - Returns: A publisher with currently playing movies as a pageable list.
244+
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
245+
func nowPlayingPublisher(page: Int?) -> AnyPublisher<MoviePageableList, TMDbError>
246+
198247
/// Publishes a list of current popular movies.
199248
///
200249
/// - Note: [TMDb API - Movie: Popular](https://developers.themoviedb.org/3/movies/get-popular-movies)
@@ -207,6 +256,32 @@ public protocol MovieService {
207256
/// - Returns: A publisher with current popular movies as a pageable list.
208257
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
209258
func popularPublisher(page: Int?) -> AnyPublisher<MoviePageableList, TMDbError>
259+
260+
/// Publishes a list of top rated movies.
261+
///
262+
/// - Note: [TMDb API - Movie: Top Rated](https://developers.themoviedb.org/3/movies/get-top-rated-movies)
263+
///
264+
/// - precondition: `page` can be between `1` and `1000`.
265+
///
266+
/// - Parameters:
267+
/// - page: The page of results to return.
268+
///
269+
/// - Returns: A publisher with top rated movies as a pageable list.
270+
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
271+
func topRatedPublisher(page: Int?) -> AnyPublisher<MoviePageableList, TMDbError>
272+
273+
/// Publishes a list of upcoming movies.
274+
///
275+
/// - Note: [TMDb API - Movie: Upcoming](https://developers.themoviedb.org/3/movies/get-upcoming)
276+
///
277+
/// - precondition: `page` can be between `1` and `1000`.
278+
///
279+
/// - Parameters:
280+
/// - page: The page of results to return.
281+
///
282+
/// - Returns: A publisher with upcoming movies as a pageable list.
283+
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
284+
func upcomingPublisher(page: Int?) -> AnyPublisher<MoviePageableList, TMDbError>
210285
#endif
211286

212287
}
@@ -227,10 +302,22 @@ public extension MovieService {
227302
completion: @escaping (Result<MoviePageableList, TMDbError>) -> Void) {
228303
fetchSimilar(toMovie: movieID, page: page, completion: completion)
229304
}
230-
305+
306+
func fetchNowPlaying(page: Int? = nil, completion: @escaping (Result<MoviePageableList, TMDbError>) -> Void) {
307+
fetchNowPlaying(page: page, completion: completion)
308+
}
309+
231310
func fetchPopular(page: Int? = nil, completion: @escaping (Result<MoviePageableList, TMDbError>) -> Void) {
232311
fetchPopular(page: page, completion: completion)
233312
}
313+
314+
func fetchTopRated(page: Int? = nil, completion: @escaping (Result<MoviePageableList, TMDbError>) -> Void) {
315+
fetchTopRated(page: page, completion: completion)
316+
}
317+
318+
func fetchUpcoming(page: Int? = nil, completion: @escaping (Result<MoviePageableList, TMDbError>) -> Void) {
319+
fetchUpcoming(page: page, completion: completion)
320+
}
234321

235322
}
236323

@@ -253,10 +340,25 @@ public extension MovieService {
253340
similarPublisher(toMovie: movieID, page: page)
254341
}
255342

343+
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
344+
func nowPlayingPublisher(page: Int? = nil) -> AnyPublisher<MoviePageableList, TMDbError> {
345+
nowPlayingPublisher(page: page)
346+
}
347+
256348
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
257349
func popularPublisher(page: Int? = nil) -> AnyPublisher<MoviePageableList, TMDbError> {
258350
popularPublisher(page: page)
259351
}
352+
353+
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
354+
func topRatedPublisher(page: Int? = nil) -> AnyPublisher<MoviePageableList, TMDbError> {
355+
topRatedPublisher(page: page)
356+
}
357+
358+
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
359+
func upcomingPublisher(page: Int? = nil) -> AnyPublisher<MoviePageableList, TMDbError> {
360+
upcomingPublisher(page: page)
361+
}
260362

261363
}
262364
#endif

Sources/TMDb/Services/Movies/MoviesEndpoint.swift

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ enum MoviesEndpoint {
1111
case videos(movieID: Movie.ID)
1212
case recommendations(movieID: Movie.ID, page: Int? = nil)
1313
case similar(movieID: Movie.ID, page: Int? = nil)
14+
case nowPlaying(page: Int? = nil)
1415
case popular(page: Int? = nil)
16+
case topRated(page: Int? = nil)
17+
case upcoming(page: Int? = nil)
1518

1619
}
1720

@@ -55,11 +58,26 @@ extension MoviesEndpoint: Endpoint {
5558
.appendingPathComponent(movieID)
5659
.appendingPathComponent("similar")
5760
.appendingPage(page)
58-
61+
62+
case .nowPlaying(let page):
63+
return Self.basePath
64+
.appendingPathComponent("now_playing")
65+
.appendingPage(page)
66+
5967
case .popular(let page):
6068
return Self.basePath
6169
.appendingPathComponent("popular")
6270
.appendingPage(page)
71+
72+
case .topRated(let page):
73+
return Self.basePath
74+
.appendingPathComponent("top_rated")
75+
.appendingPage(page)
76+
77+
case .upcoming(let page):
78+
return Self.basePath
79+
.appendingPathComponent("upcoming")
80+
.appendingPage(page)
6381
}
6482
}
6583

Sources/TMDb/Services/Movies/TMDbMovieService.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,21 @@ final class TMDbMovieService: MovieService {
4343
apiClient.get(endpoint: MoviesEndpoint.similar(movieID: movieID, page: page), completion: completion)
4444
}
4545

46+
func fetchNowPlaying(page: Int?, completion: @escaping (Result<MoviePageableList, TMDbError>) -> Void) {
47+
apiClient.get(endpoint: MoviesEndpoint.nowPlaying(page: page), completion: completion)
48+
}
49+
4650
func fetchPopular(page: Int?, completion: @escaping (Result<MoviePageableList, TMDbError>) -> Void) {
4751
apiClient.get(endpoint: MoviesEndpoint.popular(page: page), completion: completion)
4852
}
53+
54+
func fetchTopRated(page: Int?, completion: @escaping (Result<MoviePageableList, TMDbError>) -> Void) {
55+
apiClient.get(endpoint: MoviesEndpoint.topRated(page: page), completion: completion)
56+
}
57+
58+
func fetchUpcoming(page: Int?, completion: @escaping (Result<MoviePageableList, TMDbError>) -> Void) {
59+
apiClient.get(endpoint: MoviesEndpoint.upcoming(page: page), completion: completion)
60+
}
4961

5062
}
5163

@@ -88,10 +100,25 @@ extension TMDbMovieService {
88100
apiClient.get(endpoint: MoviesEndpoint.similar(movieID: movieID, page: page))
89101
}
90102

103+
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
104+
func nowPlayingPublisher(page: Int?) -> AnyPublisher<MoviePageableList, TMDbError> {
105+
apiClient.get(endpoint: MoviesEndpoint.nowPlaying(page: page))
106+
}
107+
91108
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
92109
func popularPublisher(page: Int?) -> AnyPublisher<MoviePageableList, TMDbError> {
93110
apiClient.get(endpoint: MoviesEndpoint.popular(page: page))
94111
}
112+
113+
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
114+
func topRatedPublisher(page: Int?) -> AnyPublisher<MoviePageableList, TMDbError> {
115+
apiClient.get(endpoint: MoviesEndpoint.topRated(page: page))
116+
}
117+
118+
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
119+
func upcomingPublisher(page: Int?) -> AnyPublisher<MoviePageableList, TMDbError> {
120+
apiClient.get(endpoint: MoviesEndpoint.upcoming(page: page))
121+
}
95122

96123
}
97124
#endif

Tests/TMDbTests/Mocks/Services/MockMovieService.swift

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,14 @@ final class MockMovieService: MovieService {
2424
var similar: MoviePageableList?
2525
private(set) var lastSimilarMovieID: Movie.ID?
2626
private(set) var lastSimilarPage: Int?
27+
var nowPlaying: MoviePageableList?
28+
private(set) var lastNowPlayingPage: Int?
2729
var popular: MoviePageableList?
2830
private(set) var lastPopularPage: Int?
31+
var topRated: MoviePageableList?
32+
private(set) var lastTopRatedPage: Int?
33+
var upcoming: MoviePageableList?
34+
private(set) var lastUpcomingPage: Int?
2935

3036
func fetchDetails(forMovie id: Movie.ID, completion: @escaping (Result<Movie, TMDbError>) -> Void) {
3137
lastMovieDetailsID = id
@@ -117,6 +123,18 @@ final class MockMovieService: MovieService {
117123
}
118124
}
119125

126+
func fetchNowPlaying(page: Int?, completion: @escaping (Result<MoviePageableList, TMDbError>) -> Void) {
127+
lastNowPlayingPage = page
128+
129+
guard let nowPlaying = nowPlaying else {
130+
return
131+
}
132+
133+
DispatchQueue.main.simulateWaitForNetwork {
134+
completion(.success(nowPlaying))
135+
}
136+
}
137+
120138
func fetchPopular(page: Int?, completion: @escaping (Result<MoviePageableList, TMDbError>) -> Void) {
121139
lastPopularPage = page
122140

@@ -128,6 +146,30 @@ final class MockMovieService: MovieService {
128146
completion(.success(popular))
129147
}
130148
}
149+
150+
func fetchTopRated(page: Int?, completion: @escaping (Result<MoviePageableList, TMDbError>) -> Void) {
151+
lastTopRatedPage = page
152+
153+
guard let topRated = topRated else {
154+
return
155+
}
156+
157+
DispatchQueue.main.simulateWaitForNetwork {
158+
completion(.success(topRated))
159+
}
160+
}
161+
162+
func fetchUpcoming(page: Int?, completion: @escaping (Result<MoviePageableList, TMDbError>) -> Void) {
163+
lastUpcomingPage = page
164+
165+
guard let upcoming = upcoming else {
166+
return
167+
}
168+
169+
DispatchQueue.main.simulateWaitForNetwork {
170+
completion(.success(upcoming))
171+
}
172+
}
131173

132174
}
133175

@@ -229,6 +271,19 @@ extension MockMovieService {
229271
.eraseToAnyPublisher()
230272
}
231273

274+
func nowPlayingPublisher(page: Int?) -> AnyPublisher<MoviePageableList, TMDbError> {
275+
lastNowPlayingPage = page
276+
277+
guard let nowPlaying = nowPlaying else {
278+
return Empty()
279+
.eraseToAnyPublisher()
280+
}
281+
282+
return Just(nowPlaying)
283+
.setFailureType(to: TMDbError.self)
284+
.eraseToAnyPublisher()
285+
}
286+
232287
func popularPublisher(page: Int?) -> AnyPublisher<MoviePageableList, TMDbError> {
233288
lastPopularPage = page
234289

@@ -241,6 +296,32 @@ extension MockMovieService {
241296
.setFailureType(to: TMDbError.self)
242297
.eraseToAnyPublisher()
243298
}
299+
300+
func topRatedPublisher(page: Int?) -> AnyPublisher<MoviePageableList, TMDbError> {
301+
lastTopRatedPage = page
302+
303+
guard let topRated = topRated else {
304+
return Empty()
305+
.eraseToAnyPublisher()
306+
}
307+
308+
return Just(topRated)
309+
.setFailureType(to: TMDbError.self)
310+
.eraseToAnyPublisher()
311+
}
312+
313+
func upcomingPublisher(page: Int?) -> AnyPublisher<MoviePageableList, TMDbError> {
314+
lastUpcomingPage = page
315+
316+
guard let upcoming = upcoming else {
317+
return Empty()
318+
.eraseToAnyPublisher()
319+
}
320+
321+
return Just(upcoming)
322+
.setFailureType(to: TMDbError.self)
323+
.eraseToAnyPublisher()
324+
}
244325

245326
}
246327
#endif

0 commit comments

Comments
 (0)