Swift: How to Migrate MVC to MVVM & Intro Unit Testing
1. 기능이름ViewModel.swift
생성
class 기능이름ViewModel
orstruct 기능이름ViewModel
만들기- class/struct 안에 필요한 변수와 생성자 만들기 (의존성 주입)
- 의존성 주입
struct CourseViewModel {
let name: String
// Dependency Injection (DI)
init(course: Course) {
self.name = course.name
}
}
2. VC에 있는 Model 객체(e.g. fetchArray)를 ViewModel 객체로 변경
class CoursesController: UITableViewController {
var courseViewModels = [CourseViewModel]()
...
-
API 응답안에서 응답값을 ViewModel 객체로 map해줌
fileprivate func fetchData() { Service.shared.fetchCourses { (courses, err) in if let err = err { print("Failed to fetch courses:", err) return } self.courseViewModels = courses?.map({return CourseViewModel(course: $0)}) ?? [] self.tableView.reloadData() } }
-
UITableViewCell
하위클래스에서도 Model 객체를 ViewModel 객체로 변경-
(cell class의 Model객체 변수가 didSet 될 때 셀의 내용을 구성하는 방식으로 구현했다면)
class CourseCell: UITableViewCell { var courseViewModel: CourseViewModel! { didSet { textLabel?.text = courseViewModel.name detailTextLabel?.text = courseViewModel.detailTextString accessoryType = courseViewModel.accessoryType } } ...
-
-
tableView(_:cellForRowAt:)
에서도 ViewModel 객체로 변경override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! CourseCell let courseViewModel = courseViewModels[indexPath.row] cell.courseViewModel = courseViewModel return cell }
3. cell에서 계산해서 보여줘야하는 부분은 struct 기능이름ViewModel
의 생성자에서 계산해서 만들어지도록 생성자 안에 계산로직을 넣는다. (Dependency Injection)
struct CourseViewModel {
let name: String
let detailTextString: String
let accessoryType: UITableViewCellAccessoryType
// Dependency Injection (DI)
init(course: Course) {
self.name = course.name
if course.number_of_lessons > 35 {
detailTextString = "Lessons 30+ Check it Out!"
accessoryType = .detailDisclosureButton
} else {
detailTextString = "Lessons: \(course.number_of_lessons)"
accessoryType = .none
}
}
}
댓글