📌 수정 전 SearchViewModel
class SearchViewModel: ObservableObject {
...
func loadMoreMovies() {
guard canLoadMoreMovies else { return }
Task {
do {
moviePage += 1
let moreMovies = try await NetworkManager.shared.searchMovie(with: currentQuery, page: moviePage)
DispatchQueue.main.async {
let newMovies = moreMovies.results.prefix(5)
self.movies.append(contentsOf: newMovies)
// ✅ 추가할 데이터가 더 이상 없으면 더보기 비활성화
self.canLoadMoreMovies = newMovies.count == 5
}
} catch {
print("❌ 추가 영화 로드 실패: \(error.localizedDescription)")
}
}
}
...
}
더보기 버튼 동작 개선: "검색 결과 전체보기"로 변경 & 불필요한 페이지 요청 방지
🔹 기존 문제:
- 무조건 1페이지 더 불러오는 방식 → 불필요한 API 호출 발생
- 현재 검색 결과가 10개 미만이라면 다음 페이지를 불러올 필요가 없음
- "더보기" 대신 "검색 결과 전체보기" 버튼으로 변경
✅ 1. 개선된 방식
1️⃣ 검색 결과의 첫 페이지에서 가져온 전체 개수를 기준으로 "더보기" 버튼 동작 결정
2️⃣ 현재 데이터 개수가 첫 페이지의 결과 개수보다 작을 때만 "더보기" 버튼 활성화
3️⃣ "더보기" 버튼 텍스트를 "검색 결과 전체보기"로 변경
4️⃣ 마지막 페이지까지 로드되면 버튼을 자동으로 숨김
✅ 2. SearchViewModel 수정 (불필요한 로드 방지)
import Combine
class SearchViewModel: ObservableObject {
@Published var movies: [MediaResult] = []
@Published var tvShows: [MediaResult] = []
@Published var people: [PersonResult] = []
@Published var canLoadMoreMovies = false
@Published var canLoadMoreTVShows = false
@Published var canLoadMorePeople = false
private let searchService = SearchService()
private var cancellables = Set<AnyCancellable>()
private var currentQuery = ""
private var moviePage = 1
private var tvPage = 1
private var peoplePage = 1
private var totalMoviesCount = 0
private var totalTVShowsCount = 0
private var totalPeopleCount = 0
// MARK: - 검색 실행
func search(query: String) {
currentQuery = query
resetState()
Task {
do {
let results = try await searchService.searchAll(with: query, page: 1)
DispatchQueue.main.async {
self.movies = results.movies.results
self.tvShows = results.tvShows.results
self.people = results.people.results
self.totalMoviesCount = results.movies.totalResults
self.totalTVShowsCount = results.tvShows.totalResults
self.totalPeopleCount = results.people.totalResults
self.updateLoadMoreStatus()
}
} catch {
print("❌ 검색 요청 실패: \(error.localizedDescription)")
}
}
}
// MARK: - 더보기 실행 (불필요한 요청 방지)
func loadMore(for type: MediaType) {
switch type {
case .movies:
guard movies.count < totalMoviesCount else { return }
fetchMoreMovies()
case .tvShows:
guard tvShows.count < totalTVShowsCount else { return }
fetchMoreTVShows()
case .people:
guard people.count < totalPeopleCount else { return }
fetchMorePeople()
}
}
// MARK: - API 호출하여 추가 데이터 가져오기
private func fetchMoreMovies() {
moviePage += 1
Task {
do {
let moreMovies = try await searchService.searchMovie(with: currentQuery, page: moviePage)
DispatchQueue.main.async {
self.movies.append(contentsOf: moreMovies.results)
self.updateLoadMoreStatus()
}
} catch {
print("❌ 추가 영화 로드 실패: \(error.localizedDescription)")
}
}
}
private func fetchMoreTVShows() {
tvPage += 1
Task {
do {
let moreTVShows = try await searchService.searchTV(with: currentQuery, page: tvPage)
DispatchQueue.main.async {
self.tvShows.append(contentsOf: moreTVShows.results)
self.updateLoadMoreStatus()
}
} catch {
print("❌ 추가 TV 로드 실패: \(error.localizedDescription)")
}
}
}
private func fetchMorePeople() {
peoplePage += 1
Task {
do {
let morePeople = try await searchService.searchPerson(with: currentQuery, page: peoplePage)
DispatchQueue.main.async {
self.people.append(contentsOf: morePeople.results)
self.updateLoadMoreStatus()
}
} catch {
print("❌ 추가 인물 로드 실패: \(error.localizedDescription)")
}
}
}
// MARK: - "더보기" 버튼 활성화 여부 업데이트
private func updateLoadMoreStatus() {
canLoadMoreMovies = movies.count < totalMoviesCount
canLoadMoreTVShows = tvShows.count < totalTVShowsCount
canLoadMorePeople = people.count < totalPeopleCount
}
// MARK: - 상태 초기화
private func resetState() {
moviePage = 1
tvPage = 1
peoplePage = 1
totalMoviesCount = 0
totalTVShowsCount = 0
totalPeopleCount = 0
canLoadMoreMovies = false
canLoadMoreTVShows = false
canLoadMorePeople = false
movies.removeAll()
tvShows.removeAll()
people.removeAll()
}
}
'Project > MovieClip' 카테고리의 다른 글
✅ MVVM + Combine로 설계한 검색에서 번역 기능 적용하는 최적 방법 (0) | 2025.02.23 |
---|---|
❌ 에러 분석 - UICollectionView 2번 dequeue... (0) | 2025.02.23 |
🔍 클로저를 저장하는 변수로? (0) | 2025.02.21 |
📍 함수의 역할 -> createFeaturedSection() { } (0) | 2025.02.21 |
📍함수의 역할 -> reloadData() { } (0) | 2025.02.21 |