Skip to content

Commit

Permalink
refactor: 바인딩 구조 리팩토링
Browse files Browse the repository at this point in the history
  • Loading branch information
k2645 committed Nov 19, 2024
1 parent 4da102c commit d78817a
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ final class CustomAlbumViewController: UIViewController {
return collectionView
}()
private let viewModel: CustomAlbumViewModel
private var cancellables: Set<AnyCancellable> = []
private let input = PassthroughSubject<CustomAlbumViewModel.Input, Never>()
private var cancellables = Set<AnyCancellable>()

// MARK: - Initializer
init(viewModel: CustomAlbumViewModel) {
Expand All @@ -43,7 +44,7 @@ final class CustomAlbumViewController: UIViewController {
bind()
setup()
configureConstraints()
viewModel.action(.viewDidLoad)
input.send(.viewDidLoad)
}

override func viewWillAppear(_ animated: Bool) {
Expand All @@ -54,15 +55,25 @@ final class CustomAlbumViewController: UIViewController {

// MARK: - Binding
private func bind() {
viewModel.changedAssetsOutput
.receive(on: DispatchQueue.main)
.sink { [weak self] changes in
self?.albumCollectionView.performBatchUpdates {
if let inserted = changes.insertedIndexes, !inserted.isEmpty {
self?.albumCollectionView.insertItems(at: inserted.map({ IndexPath(item: $0 + 1, section: 0) }))
}
if let removed = changes.removedIndexes, !removed.isEmpty {
self?.albumCollectionView.deleteItems(at: removed.map({ IndexPath(item: $0 + 1, section: 0) }))
let output = viewModel.transform(input: input.eraseToAnyPublisher())

output.receive(on: DispatchQueue.main)
.sink { [weak self] event in
switch event {
case .fetchAssets:
self?.albumCollectionView.reloadData()
case .changedAssets(let changes):
self?.albumCollectionView.performBatchUpdates {
if let inserted = changes.insertedIndexes, !inserted.isEmpty {
self?.albumCollectionView.insertItems(
at: inserted.map({ IndexPath(item: $0 + 1, section: 0) })
)
}
if let removed = changes.removedIndexes, !removed.isEmpty {
self?.albumCollectionView.deleteItems(
at: removed.map({ IndexPath(item: $0 + 1, section: 0) })
)
}
}
}
}
Expand Down Expand Up @@ -231,7 +242,7 @@ extension CustomAlbumViewController: UIImagePickerControllerDelegate, UINavigati
extension CustomAlbumViewController: PHPhotoLibraryChangeObserver {
nonisolated func photoLibraryDidChange(_ changeInstance: PHChange) {
Task { @MainActor in
viewModel.action(.photoDidChanged(changeInstance))
input.send(.photoDidChanged(changeInstance))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,43 @@ import MHFoundation
import Photos
import Combine

final class CustomAlbumViewModel {
final class CustomAlbumViewModel: ViewModelType {
enum Input {
case viewDidLoad
case photoDidChanged(_ changeInstance: PHChange)
}
// MARK: - Properties
@Published private(set) var photoAsset: PHFetchResult<PHAsset>?
let changedAssetsOutput = PassthroughSubject<PHFetchResultChangeDetails<PHAsset>, Never>()

func action(_ input: CustomAlbumViewModel.Input) {
switch input {
case .viewDidLoad:
fetchPhotoAssets()
case .photoDidChanged(let changeInstance):
updatePhotoAssets(changeInstance)
enum Output {
case fetchAssets
case changedAssets(_ changes: PHFetchResultChangeDetails<PHAsset>)
}

private let output = PassthroughSubject<Output, Never>()
private var cancellables = Set<AnyCancellable>()
private(set) var photoAsset: PHFetchResult<PHAsset>?

func transform(input: AnyPublisher<Input, Never>) -> AnyPublisher<Output, Never> {
input.sink { [weak self] events in
switch events {
case .viewDidLoad:
self?.fetchPhotoAssets()
case .photoDidChanged(let changeInstance):
self?.updatePhotoAssets(changeInstance)
}
}
.store(in: &cancellables)

return output.eraseToAnyPublisher()
}


private func fetchPhotoAssets() {
let fetchOptions = PHFetchOptions()
fetchOptions.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.image.rawValue)
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]

photoAsset = PHAsset.fetchAssets(with: fetchOptions)
output.send(.fetchAssets)
}

private func updatePhotoAssets(_ changeInstance: PHChange) {
Expand All @@ -35,7 +48,7 @@ final class CustomAlbumViewModel {
self.photoAsset = changes.fetchResultAfterChanges

if changes.hasIncrementalChanges {
changedAssetsOutput.send(changes)
output.send(.changedAssets(changes))
}
}
}

0 comments on commit d78817a

Please sign in to comment.