iOS/Refactoring

[UIKit/Refactoring] ExhibitionMain의 processExhibitions() 함수 리팩토링

suee97 2024. 9. 24. 02:42
private func processExhibitions() async throws {
    var processedExhibitions: [ProcessedExhibition?] = Array(repeating: nil, count: exhibitions.count)
    try await withThrowingTaskGroup(of: (Int, ProcessedExhibition?).self, body: { [weak self] taskGroup in
        guard let self else { return }
        for (idx, exhibition) in exhibitions.enumerated() {
            if let posterUrl = exhibition.posterImageUrl, let url = URL(string: posterUrl) {
                taskGroup.addTask {
                    let posterImage = await self.getExhibitionPosterImage(with: url)
                    guard let posterImage else { return (idx, nil) }
                    let dominantColor = posterImage.dominantColor()
                    let backgroundColor = self.getExhibitionBackgroundcolor(dominantColor: dominantColor)
                    let processedExhibition = ProcessedExhibition(id: Int(exhibition.id), image: posterImage, description: exhibition.description, likesCount: exhibition.likesCount, commentCount: exhibition.commentCount, likes: exhibition.likes, backgroundColor: backgroundColor)
                    return (idx, processedExhibition)
                }
            }
        }
        for try await task in taskGroup {
            processedExhibitions[task.0] = task.1
        }
    })
    self.processedExhibitions = processedExhibitions.compactMap{$0}
    processExhibitionSubject.send(self.processedExhibitions)
}

 

전시 데이터를 받아와서 처리하고 뷰에서 활용할 수 있도록하는 함수입니다.

 

이런 리뷰를 받게 되어 리팩토링을 하게 되었습니다.

 

해당 함수는 전시 데이터를 처리하는 것뿐만 아니라, 프로퍼티를 변경하고 publisher가 send하는 것까지 담당하고 있습니다.

따라서 함수의 역할을 "전시 데이터를 처리해서 뷰에 보여주기 위한 데이터를 가지고 온다"로 제한하겠습니다.

 

먼저, 함수 이름을 변경했습니다.

processExhibitions() -> getProcessedExhibitions()

그리고, 프로퍼티를 변경하고 send하는 것이 아니라, 그 전에 리턴할 수 있도록 했습니다.

 

private func getProcessedExhibitions() async throws -> [ProcessedExhibition] {
    var processedExhibitions: [ProcessedExhibition?] = Array(repeating: nil, count: exhibitions.count)
    try await withThrowingTaskGroup(of: (Int, ProcessedExhibition?).self, body: { [weak self] taskGroup in
        guard let self else { return }
        for (idx, exhibition) in exhibitions.enumerated() {
            if let posterUrl = exhibition.posterImageUrl, let url = URL(string: posterUrl) {
                taskGroup.addTask {
                    let posterImage = await self.getExhibitionPosterImage(with: url)
                    guard let posterImage else { return (idx, nil) }
                    let dominantColor = posterImage.dominantColor()
                    let backgroundColor = self.getExhibitionBackgroundcolor(dominantColor: dominantColor)
                    let processedExhibition = ProcessedExhibition(id: Int(exhibition.id), image: posterImage, description: exhibition.description, likesCount: exhibition.likesCount, commentCount: exhibition.commentCount, likes: exhibition.likes, backgroundColor: backgroundColor)
                    return (idx, processedExhibition)
                }
            }
        }
        for try await task in taskGroup {
            processedExhibitions[task.0] = task.1
        }
    })
    return processedExhibitions.compactMap{$0}
}

 

send는 해당 함수를 호출하는 context에서 수행하도록 했습니다.

func fetchExhibitions() {
    Task {
        do {
            let items = try await fetchExhibitionsUseCase.execute()
            self.exhibitions = items
            self.currentLikeStates = exhibitions.map { $0.likes }
            self.currentLikeCounts = exhibitions.map { $0.likesCount }
            self.processedExhibitions = try await getProcessedExhibitions()
            self.processExhibitionSubject.send(self.processedExhibitions)
        } catch {
            print(error)
        }
    }
}

 

이것도 사실 ... 전시를 받아오는 역할을 하는 함수에게 훨씬 많은 책임을 주는 것이지만,

시간이 없어서 다음에 고치도록 하겠습니다 ..