CollectionViewCompositionalLayout을 사용하고, 다양한 데이터를 섹션별로 구성하려는 경우, 하나의 데이터 소스를 사용하는 것이 더 효율적입니다. 왜냐하면 CollectionViewCompositionalLayout은 기본적으로 섹션 단위로 데이터를 구분하여 UI를 구성하도록 설계되어 있기 때문입니다.
아래 함수는 외부 API를 요청하는 것으로, TMDB에 요청하여 그에 맞는 데이터를 받습니다.
func fetchNowPlayingMovies(page: Int = 1) async throws -> TMDBData {
...
}
func fetchPopularMovies(page: Int = 1) async throws -> TMDBData {
...
}
func fetchTopRatedMovies(page: Int = 1) async throws -> TMDBData {
...
}
func fetchUpcomingMovies(page: Int = 1) async throws -> TMDBData {
...
}
이때, 위의 4가지의 함수를 하나의 함수로 통합하여 요청하고, 그에 맞는 데이터 모델을 세웁니다.
func fetchAllMovies() async throws -> CombineData {
// 비동기 API 호출을 동시에 실행
async let nowPlayingMovies = fetchNowPlayingMovies(page: 1)
async let popularMovies = fetchPopularMovies(page: 1)
async let topRatedMovies = fetchTopRatedMovies(page: 1)
async let upcomingMovies = fetchUpcomingMovies(page: 1)
// 모든 비동기 작업의 결과 대기
let nowPlayingResult = try await nowPlayingMovies
let popularResult = try await popularMovies
let topRatedResult = try await topRatedMovies
let upcomingResult = try await upcomingMovies
// 결과를 하나의 TMDBData 객체로 결합
var combinedData: CombineData = CombineData(combineTMDB: [])
// 각 결과를 combinedData에 추가
combinedData.combineTMDB.append(nowPlayingResult)
combinedData.combineTMDB.append(popularResult)
combinedData.combineTMDB.append(topRatedResult)
combinedData.combineTMDB.append(upcomingResult)
return combinedData
}
아래 데이터 모델을 기본적으로 제공되는 데이터 모델입니다.
import Foundation
// MARK: - Welcome
struct Welcome: Codable {
let dates: Dates
let page: Int
let results: [Result]
let totalPages, totalResults: Int
enum CodingKeys: String, CodingKey {
case dates, page, results
case totalPages = "total_pages"
case totalResults = "total_results"
}
}
// MARK: - Dates
struct Dates: Codable {
let maximum, minimum: String
}
// MARK: - Result
struct Result: Codable {
let adult: Bool
let backdropPath: String
let genreIDS: [Int]
let id: Int
let originalLanguage: OriginalLanguage
let originalTitle, overview: String
let popularity: Double
let posterPath, releaseDate, title: String
let video: Bool
let voteAverage: Double
let voteCount: Int
enum CodingKeys: String, CodingKey {
case adult
case backdropPath = "backdrop_path"
case genreIDS = "genre_ids"
case id
case originalLanguage = "original_language"
case originalTitle = "original_title"
case overview, popularity
case posterPath = "poster_path"
case releaseDate = "release_date"
case title, video
case voteAverage = "vote_average"
case voteCount = "vote_count"
}
}
enum OriginalLanguage: String, Codable {
case en = "en"
case es = "es"
case nl = "nl"
}
위의 데이터 모델을 필요한 대로 데이터 모델을 변경합니다.
TMDB를 통합한 CombineData 구조체를 새로 만들었습니다.
추가로 각 함수의 결과값에 type을 통해 구분할 수 있도록 했습니다.
import Foundation
// MARK: - Welcome
struct CombineData: Codable, Hashable{
var combineTMDB: [TMDBData]
}
struct TMDBData: Codable, Hashable {
var results: [MainResults]
var type: SectionType?
var total_pages: Int
var total_results: Int
}
// MARK: - Result
struct MainResults: Codable, Hashable {
var id: Int
var original_title: String?
var overview: String
var popularity: Double?
var poster_path: String?
var release_date: String
var title: String
var vote_average: Double?
var vote_count: Int
}
enum SectionType: String, Codable {
case noewPlayingMovie = "Now Playing Movie"
case popularMovie = "Popular Movie"
case topRatedMovie = "Top Rated Movie"
case upcomingMovie = "Upcoming Movie"
}
'Swift' 카테고리의 다른 글
ViewModel (1) | 2025.01.08 |
---|---|
setCustomSpacing(_:after:)의 역할 (0) | 2025.01.05 |
async / await 사용해보기 (0) | 2025.01.02 |
async/await란? (0) | 2024.12.18 |
async과 await 개요 (0) | 2024.12.10 |