Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Home] 정렬 버튼 누를 때마다 모드 변경 및 접근성 추가, HomeViewModel 추상화 #41

Merged
merged 6 commits into from
Feb 5, 2024

Conversation

WhiteHyun
Copy link
Member

@WhiteHyun WhiteHyun commented Feb 4, 2024

Screenshots 📸

정렬 버튼 토글 화면
RPReplay_Final1707026082



고민, 과정, 근거 💬

아키텍처 흐름 고민

각 하위 뷰마다 ViewModel을 참조하면서 동시에 하위뷰만의 @State 변수를 갖는 것은 데이터를 관리하기 어렵다고 판단하였고, ViewModelSingle source of truth가 되도록 구현했습니다.
하위뷰가 이벤트를 받으면 ViewModel에게 업데이트를 요청하고, 받아온 데이터를 다시 자신의 @State 변수에 업데이트해주는 방식을 사용했었지만,
지금은 ViewModel에게 이벤트 전달 -> ViewModel에서 State 수정 -> 변경된 State에 의해 View 재생성 -> ViewModel에게 이벤트 전달 -> ...
과 같이 단방향 흐름으로 구성했습니다.

추상화

ViewModelViewDIP원칙을 지키고 싶었습니다. 테스트를 할 때 MockViewModel을 주입하여 View의 특정 반응을 검증할 때 수월해지기 때문입니다.
그래서 View가 Concrete Type을 바라보지 않고 추상화된 타입을 바라보도록 구성하려 했으나 ViewModel은 ObservableObject를 채택해야하고, ObservableObject에는 associatedtype이 존재합니다.
결국 컴파일 시점에서 viewModel의 실제 타입 정보가 무엇으로 들어오는지 알 수 없게 됩니다.
그래서 Generic을 두어 ViewModelRepresentable을 채택한 구현체를 타입으로 두어 해결했습니다.

@MainActor protocol TestViewModelRepresentable: ObservableObject { /* ... */ }

final class TestViewModel: TestViewModelRepresentable { /* ... */ }

struct TestView1: View {
  @StateObject var viewModel: TestViewModelRepresentable // ❌ 오류
  // ...
}

// ✅ 성공
struct TestView2<T: TestViewModelRepresentable>: View {
  @StateObject var viewModel: T
}

References 📋

  1. Initialize @StateObject with a parameter in SwiftUI

- Refactored HomeViewModel and its implementations based on ReactorKit experience, utilizing `Action` and `State` for unified model management.
- Prevented multiple initializations of child views by executing onAppear code in the HomeView
@WhiteHyun WhiteHyun added 🏠 Home Home View 🔨 Implementation New feature or request labels Feb 4, 2024
@WhiteHyun WhiteHyun added this to the v2.0.0 milestone Feb 4, 2024
@WhiteHyun WhiteHyun requested a review from a team February 4, 2024 06:25
@WhiteHyun WhiteHyun self-assigned this Feb 4, 2024
@WhiteHyun WhiteHyun added the ♻️ Refactoring Refactoring Codes label Feb 4, 2024
Copy link
Contributor

@eung7 eung7 left a comment

Choose a reason for hiding this comment

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

수고하셨습니다! 😎
설명을 잘 해주셔서 금방 이해할 수 있었어요~

이렇게까지 DI에 신경써본 경험이 없었는데
이번에 이런 클린 아키텍처에 신경을 써서 공부가 많이 됩니다! ! 👍👍

@WhiteHyun WhiteHyun merged commit 11d6914 into main Feb 5, 2024
4 checks passed
@WhiteHyun WhiteHyun deleted the feature/home/37 branch February 5, 2024 12:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🏠 Home Home View 🔨 Implementation New feature or request ♻️ Refactoring Refactoring Codes
Projects
2 participants