From 25226d1b7628378b0c7894b3161bae50c2a90f50 Mon Sep 17 00:00:00 2001 From: MaraMincho <103064352+MaraMincho@users.noreply.github.com> Date: Wed, 3 Jan 2024 14:22:08 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=A6=AC=ED=94=84=EB=9E=98=EC=8B=9C=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...omeViewController+CompositionlLayout.swift | 4 +-- .../ViewController/HomeViewController.swift | 34 +++++++++++++++++-- .../HomeScene/ViewModel/HomeViewModel.swift | 15 ++++++-- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/iOS/Projects/Features/Home/Sources/Presntaion/HomeScene/ViewController/HomeViewController+CompositionlLayout.swift b/iOS/Projects/Features/Home/Sources/Presntaion/HomeScene/ViewController/HomeViewController+CompositionlLayout.swift index 4a46b46d..778d1197 100644 --- a/iOS/Projects/Features/Home/Sources/Presntaion/HomeScene/ViewController/HomeViewController+CompositionlLayout.swift +++ b/iOS/Projects/Features/Home/Sources/Presntaion/HomeScene/ViewController/HomeViewController+CompositionlLayout.swift @@ -1,5 +1,5 @@ // -// HomeViewController+CompositionalLayout.swift +// HomeViewController+CompositionlLayout.swift // HomeFeature // // Created by MaraMincho on 1/3/24. @@ -8,7 +8,7 @@ import UIKit -private extension HomeViewController { +extension HomeViewController { static func makeFeedCollectionViewLayout() -> UICollectionViewCompositionalLayout { let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)) let item = NSCollectionLayoutItem(layoutSize: itemSize) diff --git a/iOS/Projects/Features/Home/Sources/Presntaion/HomeScene/ViewController/HomeViewController.swift b/iOS/Projects/Features/Home/Sources/Presntaion/HomeScene/ViewController/HomeViewController.swift index b19a2a7b..bb87eade 100644 --- a/iOS/Projects/Features/Home/Sources/Presntaion/HomeScene/ViewController/HomeViewController.swift +++ b/iOS/Projects/Features/Home/Sources/Presntaion/HomeScene/ViewController/HomeViewController.swift @@ -7,6 +7,7 @@ // import Combine +import CombineCocoa import DesignSystem import Log import UIKit @@ -24,6 +25,7 @@ final class HomeViewController: UIViewController { private let fetchFeedPublisher: PassthroughSubject = .init() private let didDisplayFeedPublisher: PassthroughSubject = .init() + private let refreshFeedPublisher: PassthroughSubject = .init() private var feedCount: Int = 0 @@ -89,6 +91,7 @@ private extension HomeViewController { setupHierarchyAndConstraints() setNavigationItem() bind() + configureRefreshControl() fetchFeedPublisher.send() } @@ -134,7 +137,8 @@ private extension HomeViewController { let output = viewModel.transform( input: HomeViewModelInput( requestFeedPublisher: fetchFeedPublisher.eraseToAnyPublisher(), - didDisplayFeed: didDisplayFeedPublisher.eraseToAnyPublisher() + didDisplayFeed: didDisplayFeedPublisher.eraseToAnyPublisher(), + refreshFeedPublisher: refreshFeedPublisher.eraseToAnyPublisher() ) ) @@ -144,6 +148,8 @@ private extension HomeViewController { break case let .fetched(feed): self?.updateFeed(feed) + case let .refresh(feed): + self?.refreshFeed(feed) } } .store(in: &subscriptions) @@ -154,6 +160,20 @@ private extension HomeViewController { navigationItem.leftBarButtonItem = titleBarButtonItem } + func refreshFeed(_ item: [FeedElement]) { + guard let dataSource else { + return + } + var snapshot = dataSource.snapshot() + snapshot.deleteAllItems() + snapshot.appendSections([0]) + snapshot.appendItems(item) + DispatchQueue.main.async { [weak self] in + dataSource.apply(snapshot) + self?.feedListCollectionView.refreshControl?.endRefreshing() + } + } + func updateFeed(_ item: [FeedElement]) { guard let dataSource else { return @@ -168,6 +188,17 @@ private extension HomeViewController { feedCount = snapshot.numberOfItems } + func configureRefreshControl() { + // Add the refresh control to your UIScrollView object. + feedListCollectionView.refreshControl = UIRefreshControl() + feedListCollectionView.refreshControl? + .publisher(.valueChanged) + .sink { [weak self] _ in + self?.refreshFeedPublisher.send() + } + .store(in: &subscriptions) + } + enum Constants { static let navigationTitleText = "홈" } @@ -175,7 +206,6 @@ private extension HomeViewController { enum Metrics {} } - // MARK: UICollectionViewDelegate extension HomeViewController: UICollectionViewDelegate { diff --git a/iOS/Projects/Features/Home/Sources/Presntaion/HomeScene/ViewModel/HomeViewModel.swift b/iOS/Projects/Features/Home/Sources/Presntaion/HomeScene/ViewModel/HomeViewModel.swift index 25b337bc..e2d4c08b 100644 --- a/iOS/Projects/Features/Home/Sources/Presntaion/HomeScene/ViewModel/HomeViewModel.swift +++ b/iOS/Projects/Features/Home/Sources/Presntaion/HomeScene/ViewModel/HomeViewModel.swift @@ -14,6 +14,7 @@ import Foundation public struct HomeViewModelInput { let requestFeedPublisher: AnyPublisher let didDisplayFeed: AnyPublisher + let refreshFeedPublisher: AnyPublisher } public typealias HomeViewModelOutput = AnyPublisher @@ -23,6 +24,7 @@ public typealias HomeViewModelOutput = AnyPublisher public enum HomeState { case idle case fetched(feed: [FeedElement]) + case refresh(feed: [FeedElement]) } // MARK: - HomeViewModelRepresentable @@ -52,7 +54,7 @@ extension HomeViewModel: HomeViewModelRepresentable { let fetched: HomeViewModelOutput = input.requestFeedPublisher .flatMap { [useCase] _ in - useCase.fetchFeed() + return useCase.fetchFeed() } .map { feed in return HomeState.fetched(feed: feed) @@ -65,9 +67,18 @@ extension HomeViewModel: HomeViewModelRepresentable { } .store(in: &subscriptions) + let refreshed: HomeViewModelOutput = input.refreshFeedPublisher + .flatMap { [useCase] _ in + return useCase.refreshFeed() + } + .map { feed in + return HomeState.refresh(feed: feed) + } + .eraseToAnyPublisher() + let initialState: HomeViewModelOutput = Just(.idle).eraseToAnyPublisher() - return initialState.merge(with: fetched) + return initialState.merge(with: fetched, refreshed) .eraseToAnyPublisher() } }