Skip to content

Commit

Permalink
feat: 리프래시 기능 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
MaraMincho committed Jan 3, 2024
1 parent af484bd commit 25226d1
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// HomeViewController+CompositionalLayout.swift
// HomeViewController+CompositionlLayout.swift
// HomeFeature
//
// Created by MaraMincho on 1/3/24.
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

import Combine
import CombineCocoa
import DesignSystem
import Log
import UIKit
Expand All @@ -24,6 +25,7 @@ final class HomeViewController: UIViewController {

private let fetchFeedPublisher: PassthroughSubject<Void, Never> = .init()
private let didDisplayFeedPublisher: PassthroughSubject<Void, Never> = .init()
private let refreshFeedPublisher: PassthroughSubject<Void, Never> = .init()

private var feedCount: Int = 0

Expand Down Expand Up @@ -89,6 +91,7 @@ private extension HomeViewController {
setupHierarchyAndConstraints()
setNavigationItem()
bind()
configureRefreshControl()
fetchFeedPublisher.send()
}

Expand Down Expand Up @@ -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()
)
)

Expand All @@ -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)
Expand All @@ -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
Expand All @@ -168,14 +188,24 @@ 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 = ""
}

enum Metrics {}
}


// MARK: UICollectionViewDelegate

extension HomeViewController: UICollectionViewDelegate {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Foundation
public struct HomeViewModelInput {
let requestFeedPublisher: AnyPublisher<Void, Never>
let didDisplayFeed: AnyPublisher<Void, Never>
let refreshFeedPublisher: AnyPublisher<Void, Never>
}

public typealias HomeViewModelOutput = AnyPublisher<HomeState, Never>
Expand All @@ -23,6 +24,7 @@ public typealias HomeViewModelOutput = AnyPublisher<HomeState, Never>
public enum HomeState {
case idle
case fetched(feed: [FeedElement])
case refresh(feed: [FeedElement])
}

// MARK: - HomeViewModelRepresentable
Expand Down Expand Up @@ -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)
Expand All @@ -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()
}
}

0 comments on commit 25226d1

Please sign in to comment.