Conversation
요약날짜 뷰의 변경사항
예상 코드 리뷰 노력🎯 3 (중간) | ⏱️ ~20분 시
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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: 2
🧹 Nitpick comments (1)
Projects/Presentation/Sources/RoutineCreation/ViewModel/RoutineCreationViewModel.swift (1)
308-314:false방출값이 사용되지 않음 — 타입 재고 또는 제거 고려
routineCreationResultSubject.send(false)는 에러 시 방출되지만, 구독자(RoutineCreationViewController)는if creationResult { ... }조건으로false를 완전히 무시합니다. 에러 피드백은 이미networkErrorPublisher를 통해 처리됩니다.false방출이 의도된 기능 없이 미래 구독자에게 혼란을 줄 수 있습니다.♻️ 개선 방향 제안
성공만 시그널링하도록
Void퍼블리셔로 변경하거나, 또는false를 완전히 제거:-let routineCreationResultPublisher: AnyPublisher<Bool, Never> +let routineCreationResultPublisher: AnyPublisher<Void, Never>-private let routineCreationResultSubject = PassthroughSubject<Bool, Never>() +private let routineCreationResultSubject = PassthroughSubject<Void, Never>()-routineCreationResultPublisher: routineCreationResultSubject.eraseToAnyPublisher(), +routineCreationResultPublisher: routineCreationResultSubject.eraseToAnyPublisher(),try await routineUseCase.saveRoutine(routine: routine) -routineCreationResultSubject.send(true) +routineCreationResultSubject.send() networkRetryHandler.clearRetryState() } catch { -routineCreationResultSubject.send(false) networkRetryHandler.handleNetworkError(error) { [weak self] inViewController의 구독도 맞게 수정:
-.sink { [weak self] creationResult in - guard let self else { return } - if creationResult { +.sink { [weak self] in + guard let self else { return } + do { ... - } + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Projects/Presentation/Sources/RoutineCreation/ViewModel/RoutineCreationViewModel.swift` around lines 308 - 314, routineCreationResultSubject currently sends false on error but subscribers (RoutineCreationViewController) ignore false, causing redundant/ confusing emissions; change routineCreationResultSubject to emit only success (convert it to a Void/Empty-value publisher or remove the false send) by deleting the routineCreationResultSubject.send(false) in the catch block and adjusting the subject's type where it's declared (routineCreationResultSubject) and any places that subscribe to it in RoutineCreationViewController to handle only a success signal; keep existing networkRetryHandler.handleNetworkError(error){ [weak self] in self?.registerRoutine() } and leave networkErrorPublisher usage unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@Projects/Presentation/Sources/Home/View/HomeViewController.swift`:
- Around line 443-444: `routinesPublisher`가 방출되지 않을 때(네트워크 실패)
`routineScrollView.refreshControl?.endRefreshing()`가 호출되지 않아 스피너가 멈추지 않으므로,
`bind()` 내부에서 `networkErrorPublisher`에 추가 구독을 만들어 네트워크 오류 수신 시
`routineScrollView.refreshControl?.endRefreshing()`와 `hideIndicatorView()`를
호출하도록 처리하세요; 또는 `bindNetworkError`의 구현을 확장해 오류 콜백에 위 두 호출을 위임하도록 변경하여
`refreshDailyRoutine` 실패 경로에서도 항상 리프레시가 종료되게 만드세요 (참조:
routineScrollView.refreshControl?.endRefreshing(), routinesPublisher,
networkErrorPublisher, bind(), bindNetworkError, refreshDailyRoutine).
In
`@Projects/Presentation/Sources/RoutineCreation/View/RoutineCreationViewController.swift`:
- Around line 319-322: The toast shown on completion uses
viewModel.action(input: .showUpdateRoutineToastMessageView) regardless of
whether a routine was created or updated; change the branch in
RoutineCreationViewController (the isFromMypage == false path) to check
updateInfo == nil and call a distinct action for creation (e.g.,
.showCreateRoutineToastMessageView) when new, and only call
.showUpdateRoutineToastMessageView when updateInfo != nil; if the
ToastAction/Action enum or viewModel lacks a create case, add
.showCreateRoutineToastMessageView and implement handling where Toast actions
are consumed so the correct "생성" vs "수정" message is displayed, then keep the
existing popViewController(animated: true) behavior.
---
Nitpick comments:
In
`@Projects/Presentation/Sources/RoutineCreation/ViewModel/RoutineCreationViewModel.swift`:
- Around line 308-314: routineCreationResultSubject currently sends false on
error but subscribers (RoutineCreationViewController) ignore false, causing
redundant/ confusing emissions; change routineCreationResultSubject to emit only
success (convert it to a Void/Empty-value publisher or remove the false send) by
deleting the routineCreationResultSubject.send(false) in the catch block and
adjusting the subject's type where it's declared (routineCreationResultSubject)
and any places that subscribe to it in RoutineCreationViewController to handle
only a success signal; keep existing
networkRetryHandler.handleNetworkError(error){ [weak self] in
self?.registerRoutine() } and leave networkErrorPublisher usage unchanged.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
Projects/Presentation/Sources/Home/View/Component/DateView.swiftProjects/Presentation/Sources/Home/View/Component/WeekView.swiftProjects/Presentation/Sources/Home/View/HomeViewController.swiftProjects/Presentation/Sources/RoutineCreation/View/RoutineCreationViewController.swiftProjects/Presentation/Sources/RoutineCreation/ViewModel/RoutineCreationViewModel.swift
| self?.routineScrollView.refreshControl?.endRefreshing() | ||
| self?.hideIndicatorView() |
There was a problem hiding this comment.
네트워크 오류 시 refreshControl이 종료되지 않아 스피너가 무한히 표시됨
endRefreshing()이 routinesPublisher 구독 내에서만 호출됩니다. refreshDailyRoutine 액션이 네트워크 오류로 실패하면:
networkErrorPublisher로 에러 알럿이 표시됨routinesPublisher는 방출되지 않음endRefreshing()이 호출되지 않아 리프레시 스피너가 무한히 계속 돌아감
networkErrorPublisher를 처리하는 경로에서도 endRefreshing()을 호출해야 합니다.
🐛 수정 방향 제안
bind() 내에서 networkErrorPublisher에 추가 구독을 연결하거나, bindNetworkError 호출 전에 별도 처리:
+ viewModel.output.networkErrorPublisher
+ .receive(on: DispatchQueue.main)
+ .sink { [weak self] _ in
+ self?.routineScrollView.refreshControl?.endRefreshing()
+ }
+ .store(in: &cancellables)
+
bindNetworkError(from: viewModel.output.networkErrorPublisher)또는 bindNetworkError 구현 내부에서 콜백으로 처리하는 방식도 가능합니다.
📝 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.
| self?.routineScrollView.refreshControl?.endRefreshing() | |
| self?.hideIndicatorView() | |
| viewModel.output.networkErrorPublisher | |
| .receive(on: DispatchQueue.main) | |
| .sink { [weak self] _ in | |
| self?.routineScrollView.refreshControl?.endRefreshing() | |
| } | |
| .store(in: &cancellables) | |
| bindNetworkError(from: viewModel.output.networkErrorPublisher) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@Projects/Presentation/Sources/Home/View/HomeViewController.swift` around
lines 443 - 444, `routinesPublisher`가 방출되지 않을 때(네트워크 실패)
`routineScrollView.refreshControl?.endRefreshing()`가 호출되지 않아 스피너가 멈추지 않으므로,
`bind()` 내부에서 `networkErrorPublisher`에 추가 구독을 만들어 네트워크 오류 수신 시
`routineScrollView.refreshControl?.endRefreshing()`와 `hideIndicatorView()`를
호출하도록 처리하세요; 또는 `bindNetworkError`의 구현을 확장해 오류 콜백에 위 두 호출을 위임하도록 변경하여
`refreshDailyRoutine` 실패 경로에서도 항상 리프레시가 종료되게 만드세요 (참조:
routineScrollView.refreshControl?.endRefreshing(), routinesPublisher,
networkErrorPublisher, bind(), bindNetworkError, refreshDailyRoutine).
| } else { | ||
| viewModel.action(input: .showUpdateRoutineToastMessageView) | ||
| self.navigationController?.popViewController(animated: true) | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Search for showUpdatedRoutineToast usage and related message display
rg -n "showUpdatedRoutineToast" --type swift -A 5Repository: YAPP-Github/Bitnagil-iOS
Length of output: 2898
🏁 Script executed:
# Search for Korean text related to routine update/creation toast message
rg -n "수정|생성|등록" --type swift | grep -i toastRepository: YAPP-Github/Bitnagil-iOS
Length of output: 212
🏁 Script executed:
# Search for ToastMessage or toast-related views
rg -n "ToastMessage|ToastView" --type swiftRepository: YAPP-Github/Bitnagil-iOS
Length of output: 4523
🏁 Script executed:
# Check RoutineCreationViewController to see if there's different handling for new vs update
cat -n Projects/Presentation/Sources/RoutineCreation/View/RoutineCreationViewController.swift | sed -n '305,330p'Repository: YAPP-Github/Bitnagil-iOS
Length of output: 1546
🏁 Script executed:
# Check if there's a separate toast message for routine creation (vs update)
rg -n "루틴.*등록|루틴.*생성|routine.*creat" --type swift -i | head -20Repository: YAPP-Github/Bitnagil-iOS
Length of output: 3256
루틴 신규 생성 시 토스트 메시지가 "수정" 관련 문구로 표시되는 문제
isFromMypage == false 분기(라인 320)에서 호출하는 showUpdateRoutineToastMessageView는 RoutineListViewController에서 "루틴 수정이 완료되었습니다." 토스트를 표시합니다. 그런데 이 분기는 신규 루틴 생성(updateInfo == nil)도 포함하므로, 신규 등록 시에 수정 관련 문구가 표시되는 것이 부적절합니다.
신규 생성과 수정을 구분하여 각각 적절한 토스트 메시지("루틴 생성이 완료되었습니다." vs "루틴 수정이 완료되었습니다.")를 표시하도록 수정이 필요합니다.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@Projects/Presentation/Sources/RoutineCreation/View/RoutineCreationViewController.swift`
around lines 319 - 322, The toast shown on completion uses
viewModel.action(input: .showUpdateRoutineToastMessageView) regardless of
whether a routine was created or updated; change the branch in
RoutineCreationViewController (the isFromMypage == false path) to check
updateInfo == nil and call a distinct action for creation (e.g.,
.showCreateRoutineToastMessageView) when new, and only call
.showUpdateRoutineToastMessageView when updateInfo != nil; if the
ToastAction/Action enum or viewModel lacks a create case, add
.showCreateRoutineToastMessageView and implement handling where Toast actions
are consumed so the correct "생성" vs "수정" message is displayed, then keep the
existing popViewController(animated: true) behavior.
🌁 Background
홈 화면에서 발생되는 루틴 관련 오류를 수정했어요 ~~
📱 Screenshot
1. 루틴 등록 후, 홈 화면에서 바로 표시되도록 수정
Before
ScreenRecording_02-24-2026.19-45-01_1.MP4
After
ScreenRecording_02-24-2026.19-47-40_1.MP4
2. 루틴 완료 표시가 일관성을 유지하도록 수정
Before
ScreenRecording_02-24-2026.19-48-07_1.MP4
After
ScreenRecording_02-24-2026.19-45-34_1.MP4
3. 홈 화면의 pull to refresh 기능 추가
After
ScreenRecording_02-24-2026.19-46-28_1.MP4
👩💻 Contents
Summary by CodeRabbit
릴리스 노트
새로운 기능
개선 사항