From dc75e7b7a4e4be8f0025c03d90a3656ec2420832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Junnos=20=EF=A3=BF?= Date: Mon, 27 Nov 2023 21:13:15 +0900 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=EC=97=AC=EC=A0=95=20=EA=B8=B0?= =?UTF-8?q?=EB=A1=9D=EC=9D=98=20=EC=9D=B4=EB=AF=B8=EC=A7=80=EB=A5=BC=20?= =?UTF-8?q?=EB=84=A4=ED=8A=B8=EC=9B=8C=ED=81=AC=EB=A1=9C=EB=B6=80=ED=84=B0?= =?UTF-8?q?=20=EA=B0=80=EC=A0=B8=EC=98=A4=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../JourneyListViewController.swift | 34 ++++++++++++++++++- .../Cells/JourneyCell/JourneyCell.swift | 24 +++++++++++-- .../JourneyCell/SpotPhotoImageView.swift | 3 ++ 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/iOS/Features/JourneyList/Sources/JourneyList/Presentation/JourneyListViewController.swift b/iOS/Features/JourneyList/Sources/JourneyList/Presentation/JourneyListViewController.swift index 95fd6df..62d666a 100644 --- a/iOS/Features/JourneyList/Sources/JourneyList/Presentation/JourneyListViewController.swift +++ b/iOS/Features/JourneyList/Sources/JourneyList/Presentation/JourneyListViewController.swift @@ -143,14 +143,46 @@ private extension JourneyListViewController { return section } + private func fetchImage(url: URL) async throws -> Data { + let request = URLRequest(url: url) + let (data, response) = try await URLSession.shared.data(for: request) + + guard let statusCode = (response as? HTTPURLResponse)?.statusCode, + (200...299).contains(statusCode) else { throw NSError(domain: "fetch error", code: 1004) } + + return data + } + func configureDataSource() -> JourneyListDataSource { + // TODO: 최적화 & 캐싱 let cellRegistration = JourneyCellRegistration { cell, _, itemIdentifier in let cellModel = JourneyCellModel(location: itemIdentifier.location, date: itemIdentifier.date, songTitle: itemIdentifier.song.title, songArtist: itemIdentifier.song.artist) cell.update(with: cellModel) -// cell.updateImages(images: itemIdentifier.spot.photoURLs) + let photoURLs = itemIdentifier.spots + .flatMap { $0.photoURLs } + .compactMap { URL(string: $0) } + + Task { + cell.addImageView(count: photoURLs.count) + + await withTaskGroup(of: (index: Int, imageData: Data).self) { group in + for (index, photoURL) in photoURLs.enumerated() { + group.addTask(priority: .background) { [weak self] in + guard let imageData = try? await self?.fetchImage(url: photoURL) else { + return (0, Data()) + } + return (index, imageData) + } + } + + for await (index, imageData) in group { + cell.updateImages(imageData: imageData, atIndex: index) + } + } + } } let dataSource = JourneyListDataSource(collectionView: self.collectionView, diff --git a/iOS/MSUIKit/Sources/MSUIKit/Cells/JourneyCell/JourneyCell.swift b/iOS/MSUIKit/Sources/MSUIKit/Cells/JourneyCell/JourneyCell.swift index 2803faa..3fcaea8 100644 --- a/iOS/MSUIKit/Sources/MSUIKit/Cells/JourneyCell/JourneyCell.swift +++ b/iOS/MSUIKit/Sources/MSUIKit/Cells/JourneyCell/JourneyCell.swift @@ -46,6 +46,12 @@ public final class JourneyCell: UICollectionViewCell { fatalError("MusicSpot은 code-based로만 작업 중입니다.") } + public override func prepareForReuse() { + self.spotImageStack.arrangedSubviews.forEach { + $0.removeFromSuperview() + } + } + // MARK: - Functions public func update(with model: JourneyCellModel) { @@ -55,14 +61,26 @@ public final class JourneyCell: UICollectionViewCell { artist: model.song.artist) } - public func updateImages(images: [Data]) { - images.forEach { data in + @MainActor + public func addImageView(count: Int) { + (1...count).forEach { _ in let imageView = SpotPhotoImageView() - imageView.update(with: data) self.spotImageStack.addArrangedSubview(imageView) } } + @MainActor + public func updateImages(imageData: Data, atIndex index: Int) { + guard self.spotImageStack.arrangedSubviews.count > index else { + return + } + guard let imageView = self.spotImageStack.arrangedSubviews[index] as? SpotPhotoImageView else { + return + } + + imageView.update(with: imageData) + } + } // MARK: - UI Configuration diff --git a/iOS/MSUIKit/Sources/MSUIKit/Cells/JourneyCell/SpotPhotoImageView.swift b/iOS/MSUIKit/Sources/MSUIKit/Cells/JourneyCell/SpotPhotoImageView.swift index ed041f7..bbf2a88 100644 --- a/iOS/MSUIKit/Sources/MSUIKit/Cells/JourneyCell/SpotPhotoImageView.swift +++ b/iOS/MSUIKit/Sources/MSUIKit/Cells/JourneyCell/SpotPhotoImageView.swift @@ -7,6 +7,8 @@ import UIKit +import MSDesignSystem + final class SpotPhotoImageView: UIView { // MARK: - Constants @@ -50,6 +52,7 @@ final class SpotPhotoImageView: UIView { private extension SpotPhotoImageView { func configureStyle() { + self.backgroundColor = .msColor(.secondaryBackground) self.layer.cornerRadius = Metric.cornerRadius self.clipsToBounds = true }