스파르타 코딩 클럽 - iOS 스타터 6기/최종 팀 프로젝트 - 잇츠오케이

74. 스파르타 코딩 클럽 - 최종 팀 프로젝트 #16

seongpil Heo 2025. 6. 27. 20:00

  🎯  Trouble Shooting

[ 1.  또 한번의 RxDataSource Duplicate item Error ]

오늘 테스트를 위해 현위치에서 검색을 여러번 반복하던 중 

이전에 발생했던 RxDataSource Duplicate item Error가 다시 발생했다.

 

저번에도 한번 수정해서 문제를 고쳤지만 다시 발생했기에

확실하게 오류를 처리하고자 튜터님께 방문했다.

 

튜터님이 보셨을 때 해당 오류가 발생하는 이유로는 이 부분에 있을 거 같다고 말씀해주셨다.

// 가게 정보와 이미지까지 비동기로 네트워크 통신
let firstRequest = fetchStoreInfosWithImages(textQuery: selectedKeywords[0], lowLat: rect.sw.latitude, lowLon: rect.sw.longitude, highLat: rect.ne.latitude, highLon: rect.ne.longitude)
let secondRequest = fetchStoreInfosWithImages(textQuery: selectedKeywords[1], lowLat: rect.sw.latitude, lowLon: rect.sw.longitude, highLat: rect.ne.latitude, highLon: rect.ne.longitude)

return Observable.zip(firstRequest, secondRequest)
    .map { first, second in
        let merged = (first + second).sorted { $0.rating > $1.rating }
        return [StoreSection(items: merged)]
    }
    .map { .setStore($0) }

 

두개의 네트워크를 통해 가게 정보를 받아온 뒤 merge 하는 과정을 거치게 되는데

이 부분에서 중복된 가게가 발생할 수 있어 오류가 발생하는 거 같다고 말씀해주셨다.

 

따라서 두개의 가게 정보를 merge 하는 부분에서 중복을 없애는 로직을 추가하면 된다고 해주셨다.

 

[ DetailReactor - ViewDidLoad ]

return Observable.zip(firstRequest, secondRequest)
    .map { first, second in
        let merged = Array(Set((first + second).sorted { $0.rating > $1.rating }))
        return [StoreSection(items: merged)]
    }
    .map { .setStore($0) }

 

[ DetailReactor - currentLocationSearchButtonTapped ]

let firstRequest = fetchStoreInfosWithImages(textQuery: selectedKeywords[0], lowLat: sw.lat, lowLon: sw.lon, highLat: ne.lat, highLon: ne.lon)
        let secondRequest = fetchStoreInfosWithImages(textQuery: selectedKeywords[1], lowLat: sw.lat, lowLon: sw.lon, highLat: ne.lat, highLon: ne.lon)

        return Observable.zip(firstRequest, secondRequest)
            .map { [weak self] first, second in
                guard let self else { return [] }
                let merged = Array(Set(first + second))
                let sorted = self.sortStoreItems(
                                merged,
                                sortType: currentSortType,
                                centerLat: centerLat,
                                centerLon: centerLon
                            )
                return [StoreSection(items: sorted)]
            }
            .map { .setStore($0) }

 

현재 가게 정보를 검색하는 두 곳에서

중복을 없애는 방법으로 Set을 사용했는데

merge 부분에 Set과 Array를 사용해서 문제를 해결했다.

 

 

그러나 Set을 추가하니까 위와 같은 에러가 추가로 발생했는데

이건 StoreInfo에 Hashable을 채택해야 된다는 것이다.

 

해당 오류를 해결하기 위해
DetailModel에서 프로토콜을 채택을 수정하였다.

원래는 Equtable을 채택하고 있었는데 모두 Hashable로 변경하였다.

 

struct StoreInfo: Hashable {
    let displayName: String
    let primaryTypeDisplayName: String
    let formattedAddress: String
    let latitude: Double
    let longitude: Double
    let rating: Double
    let googleMapsUri: String
    let userRatingCount: Int
    let photosNames: String
    let currentOpeningHours: OpeningHours
}

struct OpeningHours: Decodable, Hashable {
    let openNow: Bool
    let periods: [Periods]
    let weekdayDescriptions: [String]?
}

extension OpeningHours {
    struct Periods: Decodable, Hashable {
        let open, close: Close
    }

    struct Close: Decodable, Hashable {
        let day, hour, minute: Int
        let date: DateClass
    }

    struct DateClass: Decodable, Hashable {
        let year, month, day: Int
    }
}

  👨🏻‍💻  오늘의 작업 

[ 1. 디테일 화면 정렬 상태관리 - RxDataSource Duplicate item Error ]

위의 TroubleShooting 참고

 

 

[ 2. PR 작성 ]

 

 

[Refactor] #129 - 디테일 화면 정렬 상태관리 by heopill · Pull Request #150 · uddt-ds/EatsOkay

📌 관련 이슈 closed: #129 📌 변경 사항 및 이유 RxDataSource Duplicate item error 문제 해결 검색 결과 두개를 merge 하는 부분에서 발생할 수 있는 RxDataSource item 중복을 Set을 사용해서 중복을 제거하여 Dupl

github.com

 

 

[ 3. Tuist를 프로젝트에 적용 ]

 

[Chore] #144 프로젝트에 Tuist 적용 by LCH-1228 · Pull Request #145 · uddt-ds/EatsOkay

📌 관련 이슈 closed: #144 📌 변경 사항 및 이유 프로젝트에 Tuist 적용 gitignore 수정 프로젝트 내 Asset 적용 부분 수정 폴더 구조 변경 📌 PR Point Tuist 설정 📌 참고 사항 Release와 Debug xcconfig 파일은

github.com