Skip to content

Commit adb750e

Browse files
committed
Feat: RecommendedRoutineView 및 RecommendedRoutineViewModel 로직 구현 (#T3-121)
- 전체 추천 루틴 받아오는 로직 추가 + 더미 데이터 삭제 - 카테고리 및 난이도에 대해 받아온 루틴 필터링하는 로직 추가 - 의존성 조립 (DataSource, Domain, Presentation)
1 parent 31034aa commit adb750e

5 files changed

Lines changed: 60 additions & 73 deletions

File tree

Projects/DataSource/Sources/Common/DataSourceDependencyAssembler.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,9 @@ public struct DataSourceDependencyAssembler: DependencyAssemblerProtocol {
2424
DIContainer.shared.register(type: UserDataRepositoryProtocol.self) { _ in
2525
return UserDataRepository()
2626
}
27+
28+
DIContainer.shared.register(type: RecommendedRoutineRepositoryProtocol.self) { _ in
29+
return RecommendedRoutineRepository()
30+
}
2731
}
2832
}

Projects/Domain/Sources/DomainDependencyAssembler.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,12 @@ public struct DomainDependencyAssembler: DependencyAssemblerProtocol {
3838

3939
return OnboardingUseCase(onboardingRepository: onboardingRepository)
4040
}
41+
42+
DIContainer.shared.register(type: RecommendedRoutineUseCaseProtocol.self) { container in
43+
guard let recommendedRoutineRepository = container.resolve(type: RecommendedRoutineRepositoryProtocol.self)
44+
else { fatalError("recommendedRoutineRepository 의존성이 등록되지 않았습니다.") }
45+
46+
return RecommendedRoutineUseCase(recommendedRoutineRepository: recommendedRoutineRepository)
47+
}
4148
}
4249
}

Projects/Presentation/Sources/Common/PresentationDependencyAssembler.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,11 @@ public struct PresentationDependencyAssembler: DependencyAssemblerProtocol {
3636
return OnboardingViewModel(onboardingUseCase: onboardingUseCase)
3737
}
3838

39-
DIContainer.shared.register(type: RecommendedRoutineViewModel.self) { _ in
40-
return RecommendedRoutineViewModel()
39+
DIContainer.shared.register(type: RecommendedRoutineViewModel.self) { container in
40+
guard let recommendedRoutineUseCase = container.resolve(type: RecommendedRoutineUseCaseProtocol.self)
41+
else { fatalError("recommendedRoutineUseCase 의존성이 등록되지 않았습니다.") }
42+
43+
return RecommendedRoutineViewModel(recommendedRoutineUseCase: recommendedRoutineUseCase)
4144
}
4245

4346
DIContainer.shared.register(type: MypageViewModel.self) { container in

Projects/Presentation/Sources/RecommendedRoutine/View/RecommendedRoutineView.swift

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//
77

88
import Combine
9+
import Domain
910
import Shared
1011
import SnapKit
1112
import UIKit
@@ -50,7 +51,7 @@ final class RecommendedRoutineView: BaseViewController<RecommendedRoutineViewMod
5051

5152
public override func viewDidLoad() {
5253
super.viewDidLoad()
53-
viewModel.action(input: .fetchRecommendedRoutines(selectedCategory: .recommendation))
54+
viewModel.action(input: .fetchRecommendedRoutines)
5455
}
5556

5657
public override func configureAttribute() {
@@ -168,10 +169,6 @@ final class RecommendedRoutineView: BaseViewController<RecommendedRoutineViewMod
168169
make.height.equalTo(Layout.routineCardHeight)
169170
}
170171
}
171-
172-
if !recommendedRoutines.isEmpty && recommendedRoutines[0].routineCategory == .recommendation {
173-
showEmotionButton()
174-
}
175172
}
176173

177174
private func showBottomSheet() {

Projects/Presentation/Sources/RecommendedRoutine/ViewModel/RecommendedRoutineViewModel.swift

Lines changed: 42 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
//
77

88
import Combine
9+
import Domain
10+
import Shared
911

1012
final class RecommendedRoutineViewModel: ViewModel {
1113
enum Input {
14+
case fetchRecommendedRoutines
1215
case selectCategory(selectedCategory: RoutineCategoryType)
1316
case selectLevel(selectedLevel: RoutineLevelType?)
14-
case fetchRecommendedRoutines(selectedCategory: RoutineCategoryType)
1517
}
1618

1719
struct Output {
@@ -21,11 +23,14 @@ final class RecommendedRoutineViewModel: ViewModel {
2123
}
2224

2325
private(set) var output: Output
26+
private var recommendedRoutines: [RecommendedRoutine] = []
2427
private let selectedCategorySubject = CurrentValueSubject<RoutineCategoryType, Never>(.recommendation)
2528
private let selectedRoutineLevelSubject = CurrentValueSubject<RoutineLevelType?, Never>(nil)
2629
private let recommendedRoutineSubject = CurrentValueSubject<[RecommendedRoutine], Never>([])
2730

28-
init() {
31+
private let recommendedRoutineUseCase: RecommendedRoutineUseCaseProtocol
32+
init(recommendedRoutineUseCase: RecommendedRoutineUseCaseProtocol) {
33+
self.recommendedRoutineUseCase = recommendedRoutineUseCase
2934
self.output = Output(
3035
selectedCategoryPublisher: selectedCategorySubject.eraseToAnyPublisher(),
3136
selectedRoutineLevelPublisher: selectedRoutineLevelSubject.eraseToAnyPublisher(),
@@ -35,90 +40,61 @@ final class RecommendedRoutineViewModel: ViewModel {
3540

3641
func action(input: Input) {
3742
switch input {
43+
case .fetchRecommendedRoutines:
44+
fetchRecommendedRoutines()
45+
3846
case .selectCategory(let selectedCategory):
3947
selectCategory(selectedCategory: selectedCategory)
4048

4149
case .selectLevel(let selectedLevel):
4250
selectLevel(selectedLevel: selectedLevel)
51+
}
52+
}
4353

44-
case .fetchRecommendedRoutines(let selectedCategory):
45-
fetchRecommendedRoutines(selectedCategory: selectedCategory)
54+
// 전체 추천 루틴을 조회합니다.
55+
private func fetchRecommendedRoutines() {
56+
Task {
57+
do {
58+
let recommendedRoutineEntities = try await recommendedRoutineUseCase.fetchRecommendedRoutines()
59+
let fetchedRecommendedRoutines = recommendedRoutineEntities.compactMap({ $0.toRecommendedRoutine() })
60+
recommendedRoutines = fetchedRecommendedRoutines
61+
62+
let currentCategory = selectedCategorySubject.value
63+
filterRecommendedRoutines(category: currentCategory, level: nil)
64+
} catch {
65+
// TODO: 에러 토스트 메시지 보여주기
66+
BitnagilLogger.log(logType: .error, message: "\(error.localizedDescription)")
67+
}
4668
}
4769
}
4870

71+
// 루틴 카테고리를 선택합니다.
4972
private func selectCategory(selectedCategory: RoutineCategoryType) {
5073
let currentCategory = selectedCategorySubject.value
5174
if currentCategory != selectedCategory {
5275
selectedCategorySubject.send(selectedCategory)
53-
fetchRecommendedRoutines(selectedCategory: selectedCategory)
76+
77+
let currentLevel = selectedRoutineLevelSubject.value
78+
filterRecommendedRoutines(category: selectedCategory, level: currentLevel)
5479
}
5580
}
5681

82+
// 루틴 난이도를 선택합니다.
5783
private func selectLevel(selectedLevel: RoutineLevelType?) {
5884
selectedRoutineLevelSubject.send(selectedLevel)
59-
// TODO: 현재 보여주고 있는 추천 루틴 난이도 필터링 해야 함
85+
86+
let currentCategory = selectedCategorySubject.value
87+
filterRecommendedRoutines(category: currentCategory, level: selectedLevel)
6088
}
6189

62-
private func fetchRecommendedRoutines(selectedCategory: RoutineCategoryType) {
63-
var recommendedRoutines: [RecommendedRoutine] = []
64-
switch selectedCategory {
65-
case .recommendation:
66-
recommendedRoutines = recommendationRoutines
67-
case .outdoor:
68-
recommendedRoutines = outdoorRoutines
69-
case .wakeup:
70-
recommendedRoutines = wakeupRoutines
71-
case .connection:
72-
recommendedRoutines = connectionRoutines
73-
case .rest:
74-
recommendedRoutines = restRoutines
75-
case .growth:
76-
recommendedRoutines = growthRoutines
90+
// 추천 루틴을 필터링합니다.
91+
private func filterRecommendedRoutines(category: RoutineCategoryType, level: RoutineLevelType?) {
92+
let filteredByCategory = recommendedRoutines.filter({ $0.routineCategory == category })
93+
if let level {
94+
let filteredByLevel = filteredByCategory.filter({ $0.routineLevel == level })
95+
recommendedRoutineSubject.send(filteredByLevel)
96+
} else {
97+
recommendedRoutineSubject.send(filteredByCategory)
7798
}
78-
recommendedRoutineSubject.send(recommendedRoutines)
7999
}
80-
81-
82-
// TODO: Dummy Data를 지우세요
83-
private let recommendationRoutines: [RecommendedRoutine] = [
84-
RecommendedRoutine(id: 1, mainTitle: "쓰레기 버리러 나가기", subTitle: "간단한 외출도 의미있는 변화예요."),
85-
RecommendedRoutine(id: 2, mainTitle: "산책하며 노란 물건 찾아보기", subTitle: "가까운 공원까지만 나가도 상쾌해져요."),
86-
RecommendedRoutine(id: 3, mainTitle: "밤 산책하며 노후 가로등 찾기", subTitle: "빛이 희미한 가로등이 있다면 제보해봐요."),
87-
RecommendedRoutine(id: 4, mainTitle: "산책하며 고장난 표지판 찾기", subTitle: "훼손된 표지판을 제보해봐요.")
88-
]
89-
90-
private let outdoorRoutines: [RecommendedRoutine] = [
91-
RecommendedRoutine(id: 1, mainTitle: "나가봐요", subTitle: "나가라꼬!!!", routineCategory: .outdoor),
92-
RecommendedRoutine(id: 2, mainTitle: "나가봐요", subTitle: "나가라꼬!!!", routineCategory: .outdoor),
93-
RecommendedRoutine(id: 3, mainTitle: "나가봐요", subTitle: "나가라꼬!!!", routineCategory: .outdoor),
94-
RecommendedRoutine(id: 4, mainTitle: "나가봐요", subTitle: "나가라꼬!!!", routineCategory: .outdoor)
95-
]
96-
97-
private let wakeupRoutines: [RecommendedRoutine] = [
98-
RecommendedRoutine(id: 1, mainTitle: "일어나요", subTitle: "일어나라꼬!!!", routineCategory: .wakeup),
99-
RecommendedRoutine(id: 2, mainTitle: "일어나요", subTitle: "일어나라꼬!!!", routineCategory: .wakeup)
100-
]
101-
102-
private let connectionRoutines: [RecommendedRoutine] = [
103-
RecommendedRoutine(id: 1, mainTitle: "연결해요", subTitle: "연결하라꼬!!!", routineCategory: .connection)
104-
]
105-
106-
private let restRoutines: [RecommendedRoutine] = [
107-
RecommendedRoutine(id: 1, mainTitle: "쉬어가요", subTitle: "쉬어갑시다아 ~~~ 아아아 ~~", routineCategory: .rest)
108-
]
109-
110-
private let growthRoutines: [RecommendedRoutine] = [
111-
RecommendedRoutine(id: 1, mainTitle: "성장해요", subTitle: "성.장.했.다", routineCategory: .growth),
112-
RecommendedRoutine(id: 2, mainTitle: "성장해요", subTitle: "성.장.했.다", routineCategory: .growth),
113-
RecommendedRoutine(id: 3, mainTitle: "성장해요", subTitle: "성.장.했.다", routineCategory: .growth),
114-
RecommendedRoutine(id: 4, mainTitle: "성장해요", subTitle: "성.장.했.다", routineCategory: .growth),
115-
RecommendedRoutine(id: 5, mainTitle: "성장해요", subTitle: "성.장.했.다", routineCategory: .growth),
116-
RecommendedRoutine(id: 6, mainTitle: "성장해요", subTitle: "성.장.했.다", routineCategory: .growth),
117-
RecommendedRoutine(id: 7, mainTitle: "성장해요", subTitle: "성.장.했.다", routineCategory: .growth),
118-
RecommendedRoutine(id: 8, mainTitle: "성장해요", subTitle: "성.장.했.다", routineCategory: .growth),
119-
RecommendedRoutine(id: 9, mainTitle: "성장해요", subTitle: "성.장.했.다", routineCategory: .growth),
120-
RecommendedRoutine(id: 10, mainTitle: "성장해요", subTitle: "성.장.했.다", routineCategory: .growth),
121-
RecommendedRoutine(id: 11, mainTitle: "성장해요", subTitle: "성.장.했.다", routineCategory: .growth),
122-
RecommendedRoutine(id: 12, mainTitle: "성장해요", subTitle: "성.장.했.다", routineCategory: .growth),
123-
]
124100
}

0 commit comments

Comments
 (0)