🔍 reloadData() { }
이 메서드는 컬렉션 뷰의 데이터를 갱신(리로드)하는 역할을 합니다.
즉, NSDiffableDataSourceSnapshot을 새로 만들어 데이터를 추가하고, 이를 dataSource에 적용하여 UI를 업데이트하는 함수입니다.
private func reloadData() {
var snapshot = NSDiffableDataSourceSnapshot<TvTMDBData, TvResultItem>()
// 섹션 추가
snapshot.appendSections(tvCombineSection.combineTMDB)
// 각 섹션의 결과를 TvResultItem으로 래핑하여 추가
for tmdbData in tvCombineSection.combineTMDB {
// 각 섹션에 명시적으로 type이 할당되어 있지 않다면 기본값(.popular) 등을 사용할 수 있음
let items = tmdbData.results.map {
TvResultItem(tvResult: $0, sectionType: tmdbData.type ?? .popular)
}
snapshot.appendItems(items, toSection: tmdbData)
}
dataSource?.apply(snapshot, animatingDifferences: true)
}
✅ 코드 분석
private func reloadData() {
var snapshot = NSDiffableDataSourceSnapshot<TvTMDBData, TvResultItem>()
NSDiffableDataSourceSnapshot<TvTMDBData, TvResultItem>()
→ 스냅샷을 생성하여 컬렉션 뷰의 현재 데이터 상태를 담을 공간을 만듦.
→ <TvTMDBData, TvResultItem>은 섹션 타입(TvTMDBData)과 아이템 타입(TvResultItem)을 정의.
1️⃣ 섹션 추가
snapshot.appendSections(tvCombineSection.combineTMDB)
tvCombineSection.combineTMDB
→ API에서 가져온 여러 개의 TvTMDBData(즉, 여러 개의 섹션 데이터)를 추가.
→ snapshot.appendSections()을 사용하여 컬렉션 뷰의 섹션을 업데이트.
2️⃣ for-in 루프에서 map을 활용하여 아이템 추가
for tmdbData in tvCombineSection.combineTMDB {
let items = tmdbData.results.map {
TvResultItem(tvResult: $0, sectionType: tmdbData.type ?? .popular)
}
snapshot.appendItems(items, toSection: tmdbData)
}
✅ for-in 루프 설명
이 부분은 각 섹션에 해당하는 아이템을 변환하여 스냅샷에 추가하는 과정입니다.
✅ map을 for-in으로 풀어서 설명하면?
var items: [TvResultItem] = []
for result in tmdbData.results {
let item = TvResultItem(tvResult: result, sectionType: tmdbData.type ?? .popular)
items.append(item)
}
현재 tvCombineSection.combineTMDB 내에 모든 데이터를 통합해서 관리하고 있지만,
각 데이터를 enum TvSectionType을 사용해 따로 관리하려면 각기 다른 배열을 열거형으로 구분해야 함.
✅ 1. TvSectionType을 기준으로 개별 배열 생성
struct TVShowDataManager {
var airingToday: [TvTMDBResult] = []
var onTheAir: [TvTMDBResult] = []
var popular: [TvTMDBResult] = []
var topRated: [TvTMDBResult] = []
}
- combineTMDB 대신, TvSectionType별로 개별 배열을 선언.
- 이제 reloadData()에서 각 배열을 TvSectionType에 매칭하면 됨
✅ 2. reloadData()
private func reloadData() {
var snapshot = NSDiffableDataSourceSnapshot<TvSectionType, TvResultItem>()
// 1️⃣ 섹션 추가
snapshot.appendSections([.airingToday, .onTheAir, .popular, .topRated])
// 2️⃣ 각 섹션별 데이터 추가
let airingTodayItems = tvShowDataManager.airingToday.map { TvResultItem(tvResult: $0, sectionType: .airingToday) }
let onTheAirItems = tvShowDataManager.onTheAir.map { TvResultItem(tvResult: $0, sectionType: .onTheAir) }
let popularItems = tvShowDataManager.popular.map { TvResultItem(tvResult: $0, sectionType: .popular) }
let topRatedItems = tvShowDataManager.topRated.map { TvResultItem(tvResult: $0, sectionType: .topRated) }
snapshot.appendItems(airingTodayItems, toSection: .airingToday)
snapshot.appendItems(onTheAirItems, toSection: .onTheAir)
snapshot.appendItems(popularItems, toSection: .popular)
snapshot.appendItems(topRatedItems, toSection: .topRated)
// 3️⃣ 데이터 적용
dataSource?.apply(snapshot, animatingDifferences: true)
}
✅ 3. createDataSource()
private func createDataSource() {
dataSource = UICollectionViewDiffableDataSource<TvSectionType, TvResultItem>(collectionView: seriesCollectionView) { collectionView, indexPath, item in
let tvTMDBResult = item.tvResult
let sectionType = item.sectionType // 이제 sectionType을 직접 가져올 수 있음
switch sectionType {
case .airingToday:
return self.configure(TvFeaturedCell.self, with: tvTMDBResult, for: indexPath)
case .onTheAir:
return self.configure(TVMediumCell.self, with: tvTMDBResult, for: indexPath)
case .popular:
return self.configure(TvFeaturedCell.self, with: tvTMDBResult, for: indexPath)
case .topRated:
return self.configure(TVSmallCell.self, with: tvTMDBResult, for: indexPath)
}
}
// 섹션 헤더 설정
dataSource?.supplementaryViewProvider = { [weak self] collectionView, kind, indexPath in
guard let sectionHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: TVSectionHeader.reuseIdentifier, for: indexPath) as? TVSectionHeader else { return nil }
let sectionType = TvSectionType.allCases[indexPath.section]
let mainTitle = sectionType.rawValue
let subTitle: String
switch sectionType {
case .airingToday:
subTitle = "오늘 방영중 TV"
case .onTheAir:
subTitle = "현재 방영 중인 TV"
case .popular:
subTitle = "인기 TV"
case .topRated:
subTitle = "순위 별 TV"
}
sectionHeader.configure(with: mainTitle, sub: subTitle)
return sectionHeader
}
}
🎯 결론
✔️ combineTMDB로 모든 데이터를 관리하는 대신 각 섹션 데이터를 개별 배열로 분리
✔️ TvSectionType을 기반으로 snapshot.appendSections()에 직접 추가
✔️ 데이터 접근이 더 직관적이고 관리하기 쉬운 구조로 변경됨
'Project > MovieClip' 카테고리의 다른 글
🔍 클로저를 저장하는 변수로? (0) | 2025.02.21 |
---|---|
📍 함수의 역할 -> createFeaturedSection() { } (0) | 2025.02.21 |
📍 함수의 역할 -> createDataSource() { } (0) | 2025.02.21 |
📍함수의 역할 -> configure<T: SelfConfiguringTVCell> () { } (0) | 2025.02.21 |
🤔 영화 정보를 통합해서 관리할 필요가 있나? (0) | 2025.02.21 |