✅ 문제 상황
json 파일에 있는 데이터를 파싱해와서 보여주는 과제를 하던 중 ViewController의 viewDidLoad()에서 데이터 로딩 로직을 처리하고 있는 것이 MVVM 패턴에 적합하지 않다고 느꼈다.
기존 코드 (문제가 있던 코드)
// BookViewController.swift
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
setupConstraints()
// 🚨 문제: ViewController에서 데이터 로딩 제어
viewModel.loadBooks { [weak self] result in
switch result {
case .success:
self?.updateUI()
case .failure(let error):
self?.showErrorAlert(error: error)
}
}
}
✅ 문제 분석
1. MVVM 패턴 위반
- ViewController (View Layer): UI만 담당해야 함
- ViewModel (Presentation Layer): 데이터 로딩과 비즈니스 로직 담당해야 함
2. 책임 분리 원칙 위반
- Single Responsibility Principle (SRP) 위반
- ViewController가 UI 관리 + 데이터 로딩 제어를 동시에 담당
3. 아키텍처 일관성 문제
- View Layer가 Presentation Logic을 처리
💡 해결 방법
// BookViewModel.swift - 개선된 코드
final class BookViewModel {
private let bookRepository: BookRepository
private var books: [Book] = []
private var selectedBookIndex: Int = 0
private(set) var error: DataServiceError?
// MARK: - Closures
var onDataLoaded: (() -> Void)?
var onError: ((DataServiceError) -> Void)?
// ✅ ViewModel이 스스로 상태를 관리하고 외부에 알림
func loadBooks() {
let result = bookRepository.loadBooks()
switch result {
case .success(let books):
self.books = books
DispatchQueue.main.async { [weak self] in
self?.onDataLoaded?()
}
case .failure(let error):
self.error = error
DispatchQueue.main.async { [weak self] in
self?.onError?(error)
}
}
}
...
}
// BookViewController.swift - 개선된 코드
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
setupConstraints()
setupBindings() // ✅ 단순히 바인딩만
viewModel.loadBooks()
}
private func setupBindings() {
viewModel.onDataLoaded = { [weak self] in
self?.updateUI()
}
viewModel.onError = { [weak self] error in
self?.showErrorAlert(error: error)
}
}
private func updateUI() {
...
}
private func showErrorAlert(error: DataServiceError) {
...
}
이렇게 ViewController는 UI 관리만
ViewModel은 데이터 변환, 로딩 로직 관리, 상태 관리를 할 수 있게 되었다!
+ 추후에 RxSwift나 Combine으로 해결해볼 예정이다
'iOS' 카테고리의 다른 글
[iOS] 성능 최적화: @inlinable과 lazy (1) | 2025.06.25 |
---|---|
[iOS] Unit Test 기본 개념과 적용 (0) | 2025.06.23 |
[아키텍처] Clean Architecture + MVVM (0) | 2025.06.13 |
[Swift] SOLID 원칙 iOS에 적용해보기 (1) | 2025.06.10 |
[iOS] 리팩토링이라 쓰고 파일분리노가다라고 읽기 (0) | 2025.05.22 |