본문 바로가기

Project/MovieClip

📍함수의 역할 -> reloadData() { }

🔍 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()에 직접 추가
✔️ 데이터 접근이 더 직관적이고 관리하기 쉬운 구조로 변경됨