Skip to content

Conversation

Genesis2010
Copy link
Contributor

✨ 해결한 이슈

🛠️ 작업내용

버튼 로딩 액션 SE 13 mini 15 pro
GIF
클립 이동 제한 15 pro
GIF

🖥️ 주요 코드 설명

이동할 클립이 존재하지 않을때

ChangeClipViewModel

let clipDataPublisher = input.changeButtonTap
    .flatMap { [weak self] _ -> AnyPublisher<[SelectClipModel]?, Never> in
        guard let self else {
            return Just([]).eraseToAnyPublisher()
        }
        
        return self.getAllCategoryAPI()
            .map { [weak self] result -> [SelectClipModel]? in
                guard let self = self else { return [] }
                
                // 2개 이하일 경우 nil 반환
                if result.count < 2 {
                    return nil
                }
                
                let sortedResult = self.sortCurrentCategoryToTop(result)
                self.collectionViewHeight = self.calculateCollectionViewHeight(numberOfItems: sortedResult.count)
                return sortedResult
            }
            .catch { error -> AnyPublisher<[SelectClipModel]?, Never> in
                print("Error: \(error)")
                return Just([]).eraseToAnyPublisher()
            }
            .eraseToAnyPublisher()
    } .eraseToAnyPublisher()

링크 이동시에 이동할 클립이 존재하지 않을때의 로직을 구현했습니다.
이동할 클립을 해당 API 로 불러 오는데 개수가 2개 미만일 경우 nil 을 반환하도록 구현했습니다. 반환값도 옵셔널을 추가해주었습니다.


DetailClipViewController

output.clipData
    .receive(on: DispatchQueue.main)
    .sink { [weak self] clipData in
        guard let self else { return }
        
        self.dismiss(animated: true) {
            // 이동할 클립이 2개 이상일 때 (전체클립 제외)
            if let data = clipData {
                self.dismiss(animated: true) {
                    self.changeClipBottom.setupSheetPresentation(bottomHeight: self.changeClipViewModel.collectionViewHeight + 180)
                    self.present(self.changeClipBottom, animated: true)
                }
                
                self.changeClipBottomSheetView.dataSourceHandler = { data }
                self.changeClipBottomSheetView.reloadChangeClipBottom()
                
            } else { // 현재 클립이 1개 존재할 때 (전체클립 제외)
                DispatchQueue.main.asyncAfter(deadline: .now()) {
                    self.showToastMessage(width: 284,
                                          status: .warning,
                                          message: "이동할 클립을 하나 이상 생성해 주세요")
                }
            }
        }
    }
    .store(in: cancelBag)

DetailClipViewController 에서 nil 값을 반환 받을 때 동작하는 로직을 추가했습니다.
다음과 같이 ToastMessage 를 출력하도록 변경하였습니다.


버튼 액션 추가

output.changeCategoryResult
    .receive(on: DispatchQueue.main)
    .sink { [weak self] result in
        guard let self else { return }
        if result == true {
            let categoryFilter = DetailCategoryFilter.allCases[viewModel.getViewModelProperty(dataType: .segmentIndex) as? Int ?? 0]
            
            self.changeClipBottom.dismiss(animated: true) {
                if self.viewModel.categoryId == 0 {
                    self.viewModel.getDetailAllCategoryAPI(filter: categoryFilter)
                } else {
                    self.viewModel.getDetailCategoryAPI(categoryID: self.viewModel.categoryId, filter: categoryFilter)
                }
            }

            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                self.showToastMessage(width: 152, 
                                      status: .check,
                                      message: "링크 이동 완료")
            }
        }
    }
    .store(in: cancelBag) completeButtonSubject

기존 로직은 VC 에서 ChangeClipBottomSheetView 의 버튼 액션을 Delegate 로 전달 받고 changeCategoryResult Publisher 로 이벤트를 전달하여 버튼 액션을 구현하고 있었습니다.

다만 고민이 됐던 부분은 버튼 액션을 처리하기 위해 task 탈출 클로저가 존재했는데 링크 이동 관련 로직은 MVVM (Input, output) 구조로 되어있어 API 를 호출하기 어려운 상황이였습니다.


final class ChangeClipBottomSheetView: UIView {
    @objc func completeBottomuttonTapped(_ sender: UIButton) {
        completeBottomButton.loadingButtonTapped(
            loadingTitle: "이동 중...",
            loadingAnimationSize: 16,
            task: { _ in
                DispatchQueue.global().asyncAfter(deadline: .now() + 0.5) {
                    self.delegate?.completButtonTap()
                }
            }
        )
    }
}

하위 View 에서 ViewModel 과 Combine 을 사용하지 않는 것을 목표로 삼고 있어서 기존의 Delegate 를 살리고자 다음과 같이 구현했습니다.
Task 구문에서 직접 API 를 호출하지 않고 기존과 동일하게 VC 에서 처리할 수 있도록 구현했습니다.


✅ Checklist

  • 필요없는 주석, 프린트문 제거했는지 확인
  • 컨벤션 지켰는지 확인

@Genesis2010 Genesis2010 added ✨ Feat 새로운 기능 구현 🚗 준혁 준혁 선생님 작업 labels Nov 5, 2024
@Genesis2010 Genesis2010 self-assigned this Nov 5, 2024
Copy link
Member

@mini-min mini-min left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

빠른 반영 감사합니다~~!
코드 확인했고 이상 없어보여요! 변경 사항 최소화해서 반영사항 적용한거 멋있어요~~ ^__^

@Genesis2010 Genesis2010 merged commit d2aabb2 into develop Nov 7, 2024
@mini-min mini-min deleted the feat/#226 branch November 7, 2024 08:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨ Feat 새로운 기능 구현 🚗 준혁 준혁 선생님 작업
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feat] 클립 이동 관련 로직 수정
2 participants