[Refactor-T3-187] 감정 구슬 등록 화면 · 추천 루틴 결과 화면 연결 - #64
Conversation
Walkthrough감정 등록 완료 화면에서 1초 지연 후 추천 루틴 결과 화면으로 내비게이션하도록 변경. 추천 루틴/루틴 생성 흐름에 마이페이지 컨텍스트 분기 추가. 결과 화면의 엔트리 포인트별 버튼/내비 동작 조정. 마이페이지 진입 시 네비게이션 바 강제 표시. 델리게이트를 통해 감정 등록 화면으로 진입 추가. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant ERC as EmotionRegisterCompletionVC
participant DI as DIContainer
participant RRMVM as ResultRecommendedRoutineViewModel
participant RRMVC as ResultRecommendedRoutineViewController
User->>ERC: 화면 표시
ERC-->>ERC: viewDidAppear (1초 지연)
ERC->>DI: resolve(ResultRecommendedRoutineViewModel)
DI-->>ERC: RRMVM
ERC->>RRMVC: init(viewModel: RRMVM, entry: .emotion)
ERC->>RRMVC: push(hidesBottomBarWhenPushed = true)
sequenceDiagram
autonumber
actor User
participant RR as RecommendedRoutineViewController
participant DI as DIContainer
participant ERVM as EmotionRegisterViewModel
participant ERVC as EmotionRegistrationViewController
User->>RR: RegisterEmotionButton 탭
RR->>DI: resolve(EmotionRegisterViewModel)
DI-->>RR: ERVM
RR->>ERVC: init(viewModel: ERVM)
RR->>ERVC: push(hidesBottomBarWhenPushed = true)
sequenceDiagram
autonumber
actor User
participant RRMVC as ResultRecommendedRoutineVC
participant Nav as UINavigationController
participant Tab as TabBarView
rect rgb(235, 245, 255)
note right of RRMVC: EntryPoint 분기 처리
alt .emotion - Skip
User->>RRMVC: Skip 탭
RRMVC->>Nav: popToRoot(animated: false)
RRMVC->>Tab: select(tabIndex: 0)
else .onboarding - Skip
User->>RRMVC: Skip 탭
RRMVC->>RRMVC: goToNextView()
RRMVC->>Tab: setAsRoot()
else .mypage - Skip
User->>RRMVC: Skip 탭
RRMVC-->>User: no-op
end
end
sequenceDiagram
autonumber
actor User
participant RC as RoutineCreationViewController
participant Nav as UINavigationController
participant Tab as TabBarView
participant VM as RoutineCreationViewModel
participant NC as NotificationCenter
User->>RC: 등록 버튼 탭
alt isFromMypage == true
RC->>Nav: popToRoot(animated: false)
RC->>Tab: select(tabIndex: 1)
RC->>VM: action(.showRecommendedRoutineToastMessageView)
VM-->>NC: post(showRecommendedRoutineToast) (지연)
else isFromMypage == false
RC->>Nav: popViewController(animated: true)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
Projects/Presentation/Sources/MyPage/View/MypageView.swift (1)
44-46: 네비게이션 바 표시 로직이 올바르게 추가되었습니다.
setNavigationBarHidden(false, animated:)호출은 마이페이지 진입 시 네비게이션 바가 확실히 표시되도록 보장하며, 애니메이션 파라미터를 존중합니다. 이는 PR의 네비게이션 플로우 조정과 잘 부합합니다.다만, 55번 라인에서
navigationController?.navigationBar.isHidden = false로 동일한 작업을 수행하고 있어 약간의 중복이 있습니다.setNavigationBarHidden(_:animated:)메서드가 선호되는 API이므로, 필요하다면 55번 라인을 제거하는 것을 고려해볼 수 있습니다.선택적으로 중복을 제거하려면 다음 diff를 적용할 수 있습니다:
navigationController?.navigationBar.standardAppearance = appearance navigationController?.navigationBar.scrollEdgeAppearance = appearance navigationController?.navigationBar.compactAppearance = appearance - navigationController?.navigationBar.isHidden = false }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
Projects/Presentation/Sources/EmotionRegister/View/EmotionRegisterCompletionViewController.swift(5 hunks)Projects/Presentation/Sources/MyPage/View/MypageView.swift(1 hunks)Projects/Presentation/Sources/RecommendedRoutine/View/RecommendedRoutineViewController.swift(2 hunks)Projects/Presentation/Sources/ResultRecommendedRoutine/View/ResultRecommendedRoutineViewController.swift(7 hunks)Projects/Presentation/Sources/ResultRecommendedRoutine/ViewModel/ResultRecommendedRoutineViewModel.swift(1 hunks)Projects/Presentation/Sources/RoutineCreation/View/RoutineCreationViewController.swift(4 hunks)Projects/Presentation/Sources/RoutineCreation/ViewModel/RoutineCreationViewModel.swift(3 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-16T09:21:15.038Z
Learnt from: choijungp
PR: YAPP-Github/Bitnagil-iOS#19
File: Projects/Presentation/Sources/Onboarding/View/OnboardingRecommendedRoutineView.swift:57-59
Timestamp: 2025-07-16T09:21:15.038Z
Learning: OnboardingRecommendedRoutineView에서 viewWillAppear에 registerOnboarding 호출하는 것이 적절한 이유: 사용자가 이전 페이지에서 온보딩 선택지를 변경한 후 돌아올 때 새로운 선택지로 다시 등록해야 하기 때문. 홈 뷰에서는 이 뷰로 돌아올 수 없어서 중복 호출 문제가 발생하지 않음.
Applied to files:
Projects/Presentation/Sources/ResultRecommendedRoutine/View/ResultRecommendedRoutineViewController.swift
🧬 Code graph analysis (5)
Projects/Presentation/Sources/RoutineCreation/View/RoutineCreationViewController.swift (2)
Projects/Presentation/Sources/ResultRecommendedRoutine/ViewModel/ResultRecommendedRoutineViewModel.swift (2)
action(56-74)showRecommendedRoutineToastMessageView(161-168)Projects/Presentation/Sources/RoutineCreation/ViewModel/RoutineCreationViewModel.swift (3)
action(83-117)registerRoutine(244-284)showRecommendedRoutineToastMessageView(286-293)
Projects/Presentation/Sources/RoutineCreation/ViewModel/RoutineCreationViewModel.swift (1)
Projects/Presentation/Sources/ResultRecommendedRoutine/ViewModel/ResultRecommendedRoutineViewModel.swift (1)
showRecommendedRoutineToastMessageView(161-168)
Projects/Presentation/Sources/ResultRecommendedRoutine/View/ResultRecommendedRoutineViewController.swift (2)
Projects/Presentation/Sources/Common/Extension/UIViewController+.swift (1)
configureCustomNavigationBar(19-29)Projects/Presentation/Sources/ResultRecommendedRoutine/ViewModel/ResultRecommendedRoutineViewModel.swift (1)
action(56-74)
Projects/Presentation/Sources/RecommendedRoutine/View/RecommendedRoutineViewController.swift (2)
Projects/Shared/Sources/DIContainer/DIContainer.swift (1)
resolve(18-25)Projects/Presentation/Sources/RecommendedRoutine/View/Component/RegisterEmotionButtonView.swift (1)
registerEmotionButtonViewDidTapRegisterButton(11-13)
Projects/Presentation/Sources/EmotionRegister/View/EmotionRegisterCompletionViewController.swift (1)
Projects/Shared/Sources/DIContainer/DIContainer.swift (1)
resolve(18-25)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (6)
Projects/Presentation/Sources/ResultRecommendedRoutine/View/ResultRecommendedRoutineViewController.swift (6)
38-61: EntryPoint enum 속성 리팩토링이 적절합니다.온보딩과 마이페이지가 동일한 동작을 하므로 케이스를 통합한 것이 깔끔합니다. 감정 등록 진입점의 경우 루틴 선택이 불가능하고(
isRoutineButtonEnabled = false), 버튼 레이블도 "맞춤 추천 루틴 보러 가기"로 차별화되어 PR 목표와 일치합니다.
130-135: 감정 진입점의 뒤로가기 버튼 제거 동작을 확인해주세요.
.withBackButton(title: "")에서.withTitle(title: "")로 변경하면서 감정 진입점에서 뒤로가기 버튼이 제거되었습니다.goToNextView()의 감정 케이스가popToRootViewController를 사용하는 것으로 보아 의도된 동작으로 보이지만, 사용자가 이전 화면(감정 등록 화면)으로 돌아갈 수 없게 됩니다. 이것이 의도된 UX인지 확인이 필요합니다.
213-222: 감정 진입점의 확인 버튼 초기 상태가 적절합니다.감정 등록 흐름에서는 루틴 선택이 불필요하므로(
isRoutineButtonEnabled = false) 확인 버튼을 처음부터 활성화(buttonState: .default)하는 것이 올바른 구현입니다.
313-335: 건너뛰기 버튼의 진입점별 동작이 정확합니다.각 진입점별 동작이 명확하게 구분되어 있습니다:
- 감정 진입점: 홈 탭(index 0)으로 이동 (PR 목표와 일치)
- 온보딩:
goToNextView()호출- 마이페이지: 동작 없음 (버튼이 숨겨져 있음)
337-358: goToNextView()의 진입점별 흐름이 PR 목표와 일치합니다.각 케이스의 동작:
- 온보딩: TabBarView로 루트 전환
- 마이페이지:
fetchSelectedRoutineId호출하여 루틴 생성 화면으로 이동- 감정: 추천 루틴 탭(index 1)으로 이동 후 토스트 표시
감정 케이스의 "맞춤 추천 보러가기" 버튼 동작이 정확하게 구현되었습니다.
360-369: RoutineCreationViewController 초기화 시그니처 확인 완료.isFromMypage가 기본값false로 정의되어 기존 호출에 영향 없으며, 마이페이지 진입점에서true로 전달하는 것도 적절합니다.
| UIAction { [weak self] _ in | ||
| self?.viewModel.action(input: .registerRoutine) | ||
| self?.navigationController?.popViewController(animated: true) | ||
| guard let self else { return } | ||
| self.viewModel.action(input: .registerRoutine) | ||
| if self.isFromMypage { | ||
| if | ||
| let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, | ||
| let window = windowScene.windows.first(where: { $0.isKeyWindow }), | ||
| let tabBarView = window.rootViewController as? TabBarView { | ||
| self.navigationController?.popToRootViewController(animated: false) | ||
| tabBarView.selectedIndex = 1 | ||
| viewModel.action(input: .showRecommendedRoutineToastMessageView) | ||
| } |
There was a problem hiding this comment.
self 누락으로 인한 컴파일 오류
UIAction 클로저 내부에서는 self를 명시해야 합니다. 현재 viewModel.action(input: .showRecommendedRoutineToastMessageView) 호출은 컴파일되지 않습니다. 아래와 같이 self.viewModel로 수정해 주세요.
- viewModel.action(input: .showRecommendedRoutineToastMessageView)
+ self.viewModel.action(input: .showRecommendedRoutineToastMessageView)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| UIAction { [weak self] _ in | |
| self?.viewModel.action(input: .registerRoutine) | |
| self?.navigationController?.popViewController(animated: true) | |
| guard let self else { return } | |
| self.viewModel.action(input: .registerRoutine) | |
| if self.isFromMypage { | |
| if | |
| let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, | |
| let window = windowScene.windows.first(where: { $0.isKeyWindow }), | |
| let tabBarView = window.rootViewController as? TabBarView { | |
| self.navigationController?.popToRootViewController(animated: false) | |
| tabBarView.selectedIndex = 1 | |
| viewModel.action(input: .showRecommendedRoutineToastMessageView) | |
| } | |
| UIAction { [weak self] _ in | |
| guard let self else { return } | |
| self.viewModel.action(input: .registerRoutine) | |
| if self.isFromMypage { | |
| if | |
| let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, | |
| let window = windowScene.windows.first(where: { $0.isKeyWindow }), | |
| let tabBarView = window.rootViewController as? TabBarView { | |
| self.navigationController?.popToRootViewController(animated: false) | |
| tabBarView.selectedIndex = 1 | |
| self.viewModel.action(input: .showRecommendedRoutineToastMessageView) | |
| } | |
| } | |
| } |
🤖 Prompt for AI Agents
Projects/Presentation/Sources/RoutineCreation/View/RoutineCreationViewController.swift
lines 145-156: inside the UIAction closure the call viewModel.action(input:
.showRecommendedRoutineToastMessageView) is missing the explicit self reference
causing a compile error; change that call to self.viewModel.action(input:
.showRecommendedRoutineToastMessageView) (keeping the existing [weak self]
capture and the guard let self else { return } intact).
taipaise
left a comment
There was a problem hiding this comment.
오늘도 고생하셨습니다!! 그리고 변경된 사항을 사진과 표로 정리해주셔서 정말로 쉽게 이해할 수 있었습니다 (아리가토~~)
🌁 Background
감정 구슬 등록 화면과 추천 루틴 결과 화면을 이어주고 감정 구슬 등록 api를 연동해주었어요 ~~
또한 추천 루틴 결과 화면이 v1과 다르게 변경되어서 그것두 수정해주었답니다 ~
📱 Screenshot
1. 온보딩
Simulator.Screen.Recording.-.iPhone.13.mini.-.2025-10-01.at.13.55.29.mp4
2. 목표 재설정
Simulator.Screen.Recording.-.iPhone.13.mini.-.2025-10-01.at.13.54.10.mp4
3. 감정 구슬 등록
Simulator.Screen.Recording.-.iPhone.13.mini.-.2025-10-01.at.13.54.43.mp4
👩💻 Contents
📝 Review Note
추천 루틴 결과 화면 동작 설명
온보딩은 v1과 동일하지만 목표 재설정과 감정 구슬 등록이 서로 바뀌듯이 수정되었습니다 !!
기존에는 목표 재설정에서는 루틴 선택이 불가능하고 확인 버튼을 통해 추천 루틴 화면으로 이동하는 것이었지만,
수정된 v2에서는 1개의 루틴을 선택하고 루틴 등록 화면으로 이동해달라는 요구사항이 있었습니다.
또한 감정 구슬 등록은 v1에서는 루틴 1개 선택 후 루틴 등록 화면으로 이동했었지만,
수정된 v2에서는 루틴 선택 불가능하고 추천 루틴 결과 목록만 확인할 수 있도록 바뀌었습니다. 😭
감정 구슬 등록 후 추천 루틴 결과 화면에서는 "맞춤 추천 보러가기" 버튼과 "건너뛰기" 버튼이 있습니다.
각 버튼의 용도는 다음과 같습니다.
다만 감정 구슬 등록은 2개의 경로로 진입할 수 있는데요 !! (홈, 추천 루틴 상단)
어떠한 경로로 진입하든 버튼의 동작은 위에 기재한 것과 동일하게 해달라는 디자이너의 요청이 있었습니다 !!!
혹시 흐름이 이해가 안되는 부분이 있다면 말씀해주세용 ~~
📣 Related Issue
Summary by CodeRabbit