Skip to content

[Feat-T3-69] 감정 등록 화면 구현#28

Merged
choijungp merged 4 commits intodevelopfrom
feat/emotionRegister
Jul 28, 2025
Merged

[Feat-T3-69] 감정 등록 화면 구현#28
choijungp merged 4 commits intodevelopfrom
feat/emotionRegister

Conversation

@choijungp
Copy link
Copy Markdown
Contributor

@choijungp choijungp commented Jul 28, 2025

🌁 Background

감정 구슬을 등록해야 합니다. .. .
이 PR은 UI 위주로 확인 부탁드립니다 !!!

📱 Screenshot

iPhone SE3 iPhone 13 mini iPhone 16 Pro
Simulator Screenshot - iPhone SE (3rd generation) - 2025-07-28 at 18 51 04 Simulator Screenshot - iPhone 13 mini - 2025-07-28 at 18 53 58 Simulator Screenshot - iPhone 16 Pro - 2025-07-28 at 19 00 54

👩‍💻 Contents

  • 감정 구슬 등록 UI 구현
  • 홈, 추천 루틴 화면에서 감정 구슬 등록 화면 연결

✅ Testing

EmotionRegisterViewModel과 EmotionRegisterView를 연동해서 "감정 등록 성공" 로그가 찍히는 것을 확인했습니다.

📝 Review Note

1. EmotionRegisterView의 emotionOrbCollectionView

스웨거를 보면 감정 구슬 목록을 받아오는 API가 있습니다. (서버 측과 얘기해본 결과 감정 구슬 값이 추가될 수 있다고 해서 api를 통해 목록 값들을 받아온다고 합니다.!)

그런 가능성이 있어 StackView가 아닌 CollectionView를 사용하여 감정 구슬들을 보여주도록 하였습니다.

또한 EmotionRegisterView에서 emotionOrbCollectionView의 Layout을 확인해보시면 subLabel 기준으로 잡혀있는데,
16 Pro에서는 약간 어색하게 느껴져셔 .. (개인적인 생각일수도)
디자이너에게 질문 남겨놓은 상황입니다 !!!!

만약 center 기준으로 잡아달라고 하면 레이아웃 수정하겠습니다 !!

Summary by CodeRabbit

  • 신규 기능
    • 감정 오브(Emotion Orb) 선택 및 등록 화면이 추가되었습니다.
    • 여섯 가지 감정(차분, 무기력, 활력, 불안, 만족, 피곤)에 대한 이미지와 타이틀이 제공됩니다.
    • 감정 선택 시 관련 이미지와 함께 컬렉션 뷰로 표시됩니다.
    • 감정 등록 결과를 실시간으로 확인할 수 있습니다.
    • 홈 및 추천 루틴 화면에서 감정 등록 화면으로 이동할 수 있습니다.

- 감정 구슬 이미지 Asset 추가
- 이미지 Asset 폴더링 정리
- BitnagilGraphic에 감정 구슬 변수 추가
- 감정 구슬 enum 타입 정의 (EmotionType)
- 감정 구슬 CollectionViewCell UI 구현 (EmotionOrbCollectionViewCell)
- 감정 구슬 등록 화면 UI 구현 (EmotionRegisterView)
@choijungp choijungp requested a review from taipaise July 28, 2025 10:11
@choijungp choijungp self-assigned this Jul 28, 2025
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jul 28, 2025

Walkthrough

새로운 감정 등록(Emotion Register) 기능이 프레젠테이션 레이어에 추가되었습니다. 감정 오브(Emotion Orb) 관련 이미지 에셋과 JSON 메타데이터가 등록되고, 감정 선택을 위한 뷰, 셀, 뷰모델, 모델(enum)이 신설되었습니다. DI 컨테이너 등록 및 기존 버튼 액션이 감정 등록 화면으로 연결되도록 수정되었습니다.

Changes

Cohort / File(s) Change Summary
Emotion Orb 이미지 에셋 및 메타데이터
Projects/Presentation/Resources/Images.xcassets/EmotionOrb/Contents.json, .../EmotionOrb/anxiety_orb.imageset/Contents.json, .../EmotionOrb/calm_orb.imageset/Contents.json, .../EmotionOrb/lethargy_orb.imageset/Contents.json, .../EmotionOrb/satisfied_orb.imageset/Contents.json, .../EmotionOrb/tired_orb.imageset/Contents.json, .../EmotionOrb/vitality_orb.imageset/Contents.json
감정 오브(Emotion Orb)별 이미지셋 및 에셋 카탈로그 메타데이터 JSON 파일이 추가됨. 각 감정별로 1x, 2x, 3x 해상도 이미지가 정의됨.
기타 에셋 메타데이터
Projects/Presentation/Resources/Images.xcassets/LoginIcon/Contents.json, .../TabBarIcon/Contents.json
LoginIcon, TabBarIcon 에셋 카탈로그에 메타데이터 JSON 파일이 추가됨.
BitnagilGraphic 확장
Projects/Presentation/Sources/Common/DesignSystem/BitnagilGraphic.swift
BitnagilGraphic enum에 감정 오브별 UIImage static 프로퍼티 6종(calm, lethargy, vitality, anxiety, satisfied, tired) 추가.
DI 등록
Projects/Presentation/Sources/Common/PresentationDependencyAssembler.swift
EmotionRegisterViewModel이 DI 컨테이너에 등록됨.
EmotionType 모델
Projects/Presentation/Sources/EmotionRegister/Model/EmotionType.swift
감정 상태 6종(calm, lethargy, vitality, anxiety, satisfied, tired)을 나타내는 EmotionType enum 신설. 각 케이스별 title(한글), image(UIImage?) 프로퍼티 제공.
감정 오브 셀
Projects/Presentation/Sources/EmotionRegister/View/Component/EmotionOrbCollectionViewCell.swift
EmotionType을 보여주는 커스텀 UICollectionViewCell 클래스(EmotionOrbCollectionViewCell) 신설.
감정 등록 뷰
Projects/Presentation/Sources/EmotionRegister/View/EmotionRegisterView.swift
감정 선택 및 등록을 위한 UIViewController(EmotionRegisterView) 신설. 컬렉션뷰로 감정 선택, 선택 시 ViewModel에 액션 전달, 결과 구독.
감정 등록 뷰모델
Projects/Presentation/Sources/EmotionRegister/ViewModel/EmotionRegisterViewModel.swift
EmotionRegisterViewModel 클래스 신설. Combine을 활용해 입력(Input)과 출력(Output) 구조 제공, 감정 선택 시 성공 신호 발행(서버 연동은 추후 구현 예정).
HomeView, RecommendedRoutineView 버튼 액션
Projects/Presentation/Sources/Home/View/HomeView.swift, .../RecommendedRoutine/View/RecommendedRoutineView.swift
registerEmotionButton 액션이 실제로 EmotionRegisterViewModel을 DI 컨테이너에서 resolve하여 EmotionRegisterView로 네비게이션하도록 구현됨.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant HomeView
    participant DIContainer
    participant EmotionRegisterViewModel
    participant EmotionRegisterView

    User->>HomeView: registerEmotionButton 탭
    HomeView->>DIContainer: EmotionRegisterViewModel resolve
    DIContainer-->>HomeView: ViewModel 인스턴스
    HomeView->>EmotionRegisterView: 생성 및 push
    User->>EmotionRegisterView: 감정 오브 선택
    EmotionRegisterView->>EmotionRegisterViewModel: action(input: .selectEmotion)
    EmotionRegisterViewModel->>EmotionRegisterViewModel: registerEmotion (임시 성공 처리)
    EmotionRegisterViewModel-->>EmotionRegisterView: registerEmotionResultPublisher(true)
    EmotionRegisterView->>User: 결과 처리 (로그 등)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~18 minutes

Poem

🥚
감정 오브가 둥글게,
토끼는 셀을 꾸미네.
컬렉션 뷰에 감정 띄우고,
버튼 누르면 뷰모델로 go!
DI로 이어지는 감정의 길,
오늘도 코드밭에 행복을 심네.
🐰✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/emotionRegister

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary or @coderabbitai 요약 to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (9)
Projects/Presentation/Sources/Home/View/HomeView.swift (1)

98-105: 감정 등록 화면으로의 네비게이션 구현이 적절합니다.

의존성 주입과 네비게이션 스택 푸시 로직이 올바르게 구현되었습니다. weak self 캡처로 메모리 리크도 방지하고 있습니다.

다만 fatalError 대신 더 우아한 에러 처리를 고려해보세요. 이전 학습 내용에 따르면 추후 CustomAlertView를 통한 UI 에러 처리를 계획하고 계신 것으로 보입니다.

Projects/Presentation/Sources/EmotionRegister/Model/EmotionType.swift (1)

10-39: 감정 타입 모델이 깔끔하게 설계되었습니다.

CaseIterable 프로토콜 준수로 반복 가능하고, computed property로 제목과 이미지를 제공하는 구조가 적절합니다. 옵셔널 이미지 반환으로 안전성도 고려했습니다.

현재는 한국어 제목이 하드코딩되어 있는데, 향후 다국어 지원을 고려한다면 Localizable.strings 활용을 검토해보세요.

Projects/Presentation/Sources/RecommendedRoutine/View/RecommendedRoutineView.swift (1)

77-84: HomeView와 일관된 감정 등록 네비게이션 구현입니다.

HomeView와 동일한 패턴으로 구현되어 일관성이 좋습니다. 다만 HomeView와 동일하게 fatalError 대신 더 우아한 에러 처리 방식을 고려해보세요.

Projects/Presentation/Sources/EmotionRegister/ViewModel/EmotionRegisterViewModel.swift (3)

34-37: 서버 통신 로직 구현 준비 완료.

현재는 placeholder 로직이지만 구조는 잘 준비되어 있습니다. 서버 통신 로직 구현 시 에러 처리도 함께 고려해주세요.

서버 통신 로직 구현이나 에러 처리 패턴에 대한 도움이 필요하시면 언제든 말씀해주세요!


10-38: MVVM 패턴이 잘 구현되었습니다!

Input/Output 구조와 Combine을 활용한 반응형 프로그래밍 패턴이 적절하게 적용되었습니다. 다만 향후 서버 통신 구현 시 에러 처리를 고려해보세요.

현재 구현은 항상 성공을 반환하고 있는데, 향후 서버 통신 구현 시 에러 케이스 처리가 필요할 것 같습니다. 에러 타입 정의나 실패 케이스 처리 로직 구현에 도움이 필요하시면 말씀해 주세요.


35-36: 서버 통신 로직 구현 계획을 확인해주세요.

TODO 주석으로 표시된 서버 통신 로직의 구현 일정이나 계획이 있는지 확인이 필요합니다.

서버 통신 로직 구현에 도움이 필요하거나 이슈로 등록하여 추적하고 싶으시다면 도움을 드릴 수 있습니다.

Projects/Presentation/Sources/EmotionRegister/View/EmotionRegisterView.swift (3)

53-55: 불필요한 오버라이드 제거 권장.

현재 viewDidLoad는 super 호출만 하고 있어 불필요합니다. 추가 로직이 필요하지 않다면 제거하는 것이 좋겠습니다.

-    override func viewDidLoad() {
-        super.viewDidLoad()
-    }

15-27: 레이아웃 상수들이 잘 정의되었습니다.

Layout enum을 통해 UI 상수들을 체계적으로 관리하고 있어 좋습니다. 다만 일부 값들은 디자인 시스템으로 통합하는 것을 고려해보세요.

향후 디자인 시스템이 확장되면 spacing이나 size 관련 상수들을 공통 디자인 토큰으로 관리하는 것을 검토해보세요.


53-55: 불필요한 오버라이드를 제거하세요.

viewDidLoad에서 super 호출 외에 다른 로직이 없으므로 오버라이드가 불필요합니다.

-    override func viewDidLoad() {
-        super.viewDidLoad()
-    }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 20aebe5 and 799db5d.

⛔ Files ignored due to path filters (48)
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/anxiety_orb.imageset/anxiety_orb.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/anxiety_orb.imageset/anxiety_orb@2x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/anxiety_orb.imageset/anxiety_orb@3x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/calm_orb.imageset/calm_orb.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/calm_orb.imageset/calm_orb@2x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/calm_orb.imageset/calm_orb@3x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/lethargy_orb.imageset/lethargy_orb.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/lethargy_orb.imageset/lethargy_orb@2x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/lethargy_orb.imageset/lethargy_orb@3x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/satisfied_orb.imageset/satisfied_orb.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/satisfied_orb.imageset/satisfied_orb@2x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/satisfied_orb.imageset/satisfied_orb@3x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/tired_orb.imageset/tired_orb.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/tired_orb.imageset/tired_orb@2x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/tired_orb.imageset/tired_orb@3x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/vitality_orb.imageset/vitality_orb.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/vitality_orb.imageset/vitality_orb@2x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/vitality_orb.imageset/vitality_orb@3x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/LoginIcon/apple_icon.imageset/apple_icon.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/LoginIcon/apple_icon.imageset/apple_icon@2x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/LoginIcon/apple_icon.imageset/apple_icon@3x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/LoginIcon/kakao_icon.imageset/kakao_icon.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/LoginIcon/kakao_icon.imageset/kakao_icon@2x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/LoginIcon/kakao_icon.imageset/kakao_icon@3x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/home_empty_icon.imageset/navigation=home, status=empty.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/home_empty_icon.imageset/navigation=home, status=empty@2x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/home_empty_icon.imageset/navigation=home, status=empty@3x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/home_fill_icon.imageset/navigation=home, status=fill.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/home_fill_icon.imageset/navigation=home, status=fill@2x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/home_fill_icon.imageset/navigation=home, status=fill@3x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/mypage_empty_icon.imageset/navigation=_mypage, status=empty.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/mypage_empty_icon.imageset/navigation=_mypage, status=empty@2x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/mypage_empty_icon.imageset/navigation=_mypage, status=empty@3x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/mypage_fill_icon.imageset/navigation=_mypage, status=fill.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/mypage_fill_icon.imageset/navigation=_mypage, status=fill@2x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/mypage_fill_icon.imageset/navigation=_mypage, status=fill@3x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/recommend_empty_icon.imageset/navigation=recommend, status=empty.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/recommend_empty_icon.imageset/navigation=recommend, status=empty@2x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/recommend_empty_icon.imageset/navigation=recommend, status=empty@3x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/recommend_fill_icon.imageset/navigation=recommend, status=fill.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/recommend_fill_icon.imageset/navigation=recommend, status=fill@2x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/recommend_fill_icon.imageset/navigation=recommend, status=fill@3x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/report_empty_icon.imageset/navigation=report, status=empty.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/report_empty_icon.imageset/navigation=report, status=empty@2x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/report_empty_icon.imageset/navigation=report, status=empty@3x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/report_fill_icon.imageset/navigation=report, status=fill.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/report_fill_icon.imageset/navigation=report, status=fill@2x.png is excluded by !**/*.png
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/report_fill_icon.imageset/navigation=report, status=fill@3x.png is excluded by !**/*.png
📒 Files selected for processing (17)
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/Contents.json (1 hunks)
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/anxiety_orb.imageset/Contents.json (1 hunks)
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/calm_orb.imageset/Contents.json (1 hunks)
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/lethargy_orb.imageset/Contents.json (1 hunks)
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/satisfied_orb.imageset/Contents.json (1 hunks)
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/tired_orb.imageset/Contents.json (1 hunks)
  • Projects/Presentation/Resources/Images.xcassets/EmotionOrb/vitality_orb.imageset/Contents.json (1 hunks)
  • Projects/Presentation/Resources/Images.xcassets/LoginIcon/Contents.json (1 hunks)
  • Projects/Presentation/Resources/Images.xcassets/TabBarIcon/Contents.json (1 hunks)
  • Projects/Presentation/Sources/Common/DesignSystem/BitnagilGraphic.swift (1 hunks)
  • Projects/Presentation/Sources/Common/PresentationDependencyAssembler.swift (1 hunks)
  • Projects/Presentation/Sources/EmotionRegister/Model/EmotionType.swift (1 hunks)
  • Projects/Presentation/Sources/EmotionRegister/View/Component/EmotionOrbCollectionViewCell.swift (1 hunks)
  • Projects/Presentation/Sources/EmotionRegister/View/EmotionRegisterView.swift (1 hunks)
  • Projects/Presentation/Sources/EmotionRegister/ViewModel/EmotionRegisterViewModel.swift (1 hunks)
  • Projects/Presentation/Sources/Home/View/HomeView.swift (1 hunks)
  • Projects/Presentation/Sources/RecommendedRoutine/View/RecommendedRoutineView.swift (2 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: choijungp
PR: YAPP-Github/Bitnagil-iOS#19
File: Projects/Presentation/Sources/Common/PresentationDependencyAssembler.swift:0-0
Timestamp: 2025-07-16T10:57:16.559Z
Learning: choijungp는 추후 CustomAlertView를 만들어서 에러 처리를 UI로 해결하도록 수정할 계획을 가지고 있음.
Learnt from: choijungp
PR: YAPP-Github/Bitnagil-iOS#19
File: Projects/Domain/Sources/UseCase/Onboarding/OnboardingUseCase.swift:0-0
Timestamp: 2025-07-16T10:58:30.858Z
Learning: choijungp는 OnboardingUseCase의 convertToDictionary 함수에서 에러 처리 개선을 추후 고민하고 반영할 계획을 가지고 있음.
Projects/Presentation/Sources/Home/View/HomeView.swift (1)

Learnt from: choijungp
PR: #19
File: Projects/Presentation/Sources/Onboarding/View/OnboardingRecommendedRoutineView.swift:57-59
Timestamp: 2025-07-16T09:21:15.038Z
Learning: OnboardingRecommendedRoutineView에서 viewWillAppear에 registerOnboarding 호출하는 것이 적절한 이유: 사용자가 이전 페이지에서 온보딩 선택지를 변경한 후 돌아올 때 새로운 선택지로 다시 등록해야 하기 때문. 홈 뷰에서는 이 뷰로 돌아올 수 없어서 중복 호출 문제가 발생하지 않음.

Projects/Presentation/Sources/RecommendedRoutine/View/RecommendedRoutineView.swift (3)

Learnt from: choijungp
PR: #19
File: Projects/Presentation/Sources/Onboarding/View/OnboardingRecommendedRoutineView.swift:57-59
Timestamp: 2025-07-16T09:21:15.038Z
Learning: OnboardingRecommendedRoutineView에서 viewWillAppear에 registerOnboarding 호출하는 것이 적절한 이유: 사용자가 이전 페이지에서 온보딩 선택지를 변경한 후 돌아올 때 새로운 선택지로 다시 등록해야 하기 때문. 홈 뷰에서는 이 뷰로 돌아올 수 없어서 중복 호출 문제가 발생하지 않음.

Learnt from: choijungp
PR: #19
File: Projects/Presentation/Sources/Login/View/TermsAgreementView.swift:44-46
Timestamp: 2025-07-16T09:09:13.869Z
Learning: BaseViewController의 viewDidLoad() 메서드에서 이미 configureAttribute(), configureLayout(), bind()를 호출하므로, 하위 클래스에서 super.viewDidLoad()를 호출하면 이 메서드들이 자동으로 호출된다. 따라서 하위 클래스에서 추가로 호출할 필요가 없다.

Learnt from: choijungp
PR: #19
File: Projects/Presentation/Sources/Login/View/TermsAgreementView.swift:44-46
Timestamp: 2025-07-16T09:09:13.869Z
Learning: BaseViewController의 viewDidLoad() 메서드에서 이미 configureAttribute(), configureLayout(), bind()를 호출하므로, 하위 클래스에서 super.viewDidLoad()를 호출하면 이 메서드들이 자동으로 호출된다. 따라서 하위 클래스에서 추가로 호출할 필요가 없다.

Projects/Presentation/Sources/EmotionRegister/View/EmotionRegisterView.swift (1)

Learnt from: choijungp
PR: #19
File: Projects/Presentation/Sources/Onboarding/View/OnboardingRecommendedRoutineView.swift:57-59
Timestamp: 2025-07-16T09:21:15.038Z
Learning: OnboardingRecommendedRoutineView에서 viewWillAppear에 registerOnboarding 호출하는 것이 적절한 이유: 사용자가 이전 페이지에서 온보딩 선택지를 변경한 후 돌아올 때 새로운 선택지로 다시 등록해야 하기 때문. 홈 뷰에서는 이 뷰로 돌아올 수 없어서 중복 호출 문제가 발생하지 않음.

🪛 SwiftLint (0.57.0)
Projects/Presentation/Sources/EmotionRegister/ViewModel/EmotionRegisterViewModel.swift

[Warning] 35-35: TODOs should be resolved (서버 통신 로직)

(todo)

Projects/Presentation/Sources/EmotionRegister/View/EmotionRegisterView.swift

[Warning] 113-113: TODOs should be resolved (추천 루틴 화면 보여주기)

(todo)


[Warning] 53-53: Remove overridden functions that don't do anything except call their super

(unneeded_override)

🔇 Additional comments (20)
Projects/Presentation/Resources/Images.xcassets/LoginIcon/Contents.json (1)

1-6: LoginIcon 폴더가 이미지 세트로 인식되지 않을 가능성 확인 필요
폴더명이 LoginIcon(확장자 없음)이라 Xcode 에셋 카탈로그에서는 단순 그룹으로 처리됩니다. 실제 이미지를 로드하려면 LoginIcon.imageset 하위에 이미지와 Contents.json이 존재해야 합니다. 현재 구조로도 문제가 없다면 그대로 두어도 되지만, 의도한 대로 이미지 접근이 가능한지 한 번 더 점검해 주세요.

Projects/Presentation/Resources/Images.xcassets/TabBarIcon/Contents.json (1)

1-6: TabBarIcon 폴더 구조 확인 권장
TabBarIcon 역시 확장자가 없어 그룹으로만 인식됩니다. 실제 이미지 세트(*.imageset)가 존재하는지, 코드에서 UIImage(named:) 호출 시 문제없는지 확인 부탁드립니다.

Projects/Presentation/Resources/Images.xcassets/EmotionOrb/Contents.json (1)

1-6: 에셋 그룹 메타데이터 이상 없음
EmotionOrb는 여러 .imageset을 포함하는 상위 그룹으로 보이며, 메타데이터도 문제 없습니다.

Projects/Presentation/Resources/Images.xcassets/EmotionOrb/anxiety_orb.imageset/Contents.json (1)

1-23: 이미지 세트 정의 정상
1x·2x·3x 스케일 전부 선언되어 있고 idiom도 universal로 지정되어 있어 문제가 없습니다.

Projects/Presentation/Resources/Images.xcassets/EmotionOrb/tired_orb.imageset/Contents.json (1)

1-23: 이미지 세트 정의 정상
tired_orb 이미지 세트도 스케일·idiom 설정이 올바르게 되어 있습니다.

Projects/Presentation/Resources/Images.xcassets/EmotionOrb/lethargy_orb.imageset/Contents.json (1)

1-23: LGTM!

표준 Xcode 애셋 카탈로그 JSON 구조를 올바르게 따르고 있습니다. 파일명 규칙(@2x, @3x)과 스케일 팩터가 적절하게 설정되어 있습니다.

Projects/Presentation/Resources/Images.xcassets/EmotionOrb/calm_orb.imageset/Contents.json (1)

1-23: LGTM!

다른 감정 오브 애셋과 일관된 구조를 가지고 있으며, 표준 애셋 카탈로그 형식을 올바르게 따르고 있습니다.

Projects/Presentation/Sources/Common/PresentationDependencyAssembler.swift (1)

50-52: LGTM!

EmotionRegisterViewModel의 DI 등록이 다른 뷰모델들과 일관된 패턴을 따르고 있습니다. 현재는 의존성이 없는 단순한 구조로 되어 있는데, 향후 감정 등록 API 연동이나 데이터 저장 기능이 추가될 때 UseCase나 Repository 의존성 주입이 필요할 수 있습니다.

Projects/Presentation/Resources/Images.xcassets/EmotionOrb/satisfied_orb.imageset/Contents.json (1)

1-23: LGTM!

다른 감정 오브 애셋들과 동일한 구조와 명명 규칙을 따르고 있어 일관성이 유지되고 있습니다.

Projects/Presentation/Resources/Images.xcassets/EmotionOrb/vitality_orb.imageset/Contents.json (1)

1-23: LGTM!

모든 감정 오브 애셋 파일들이 일관된 구조를 유지하고 있어, 유지보수성과 코드 품질이 좋습니다. 표준 애셋 카탈로그 형식을 올바르게 따르고 있습니다.

Projects/Presentation/Sources/Common/DesignSystem/BitnagilGraphic.swift (1)

17-23: 감정 오브 이미지 에셋 추가가 깔끔하게 구현되었습니다.

기존 패턴과 일관성 있게 구현되었고, MARK 주석으로 섹션을 명확히 구분했습니다. 이미지 에셋 명명 규칙도 적절합니다.

Projects/Presentation/Sources/RecommendedRoutine/View/RecommendedRoutineView.swift (1)

9-9: Shared 모듈 import가 적절합니다.

DIContainer 사용을 위해 필요한 import입니다.

Projects/Presentation/Sources/EmotionRegister/View/Component/EmotionOrbCollectionViewCell.swift (1)

11-60: 감정 오브 컬렉션뷰 셀이 표준 패턴에 따라 잘 구현되었습니다.

  • Layout 상수로 깔끔한 구성
  • SnapKit을 활용한 명확한 레이아웃 설정
  • configureCell 메서드로 깔끔한 인터페이스 제공
  • 디자인 시스템(BitnagilFont, BitnagilColor) 일관성 유지

96x96 이미지 크기도 감정 오브 표시에 적절해 보입니다.

Projects/Presentation/Sources/EmotionRegister/ViewModel/EmotionRegisterViewModel.swift (2)

10-25: 깔끔한 MVVM 구조 구현!

Input-Output 패턴과 Combine을 활용한 반응형 구조가 잘 구현되어 있습니다. 기존 코드베이스의 ViewModel 패턴을 일관성 있게 따르고 있어 좋습니다.


27-32: 액션 처리 로직이 깔끔합니다.

입력에 따른 적절한 분기 처리와 private 메서드로의 위임이 잘 구현되어 있습니다.

Projects/Presentation/Sources/EmotionRegister/View/EmotionRegisterView.swift (5)

15-27: 레이아웃 상수 구성이 깔끔합니다.

Layout enum을 통한 상수 관리가 잘 되어 있고, 네이밍도 명확해서 유지보수가 용이할 것 같습니다.


31-78: 컬렉션 뷰 설정이 적절합니다.

FlowLayout 구성과 셀 등록, delegate 설정이 표준 패턴을 잘 따르고 있습니다. PR 목표에서 언급한 대로 동적 API 업데이트를 위한 CollectionView 선택이 적절합니다.


123-145: 컬렉션 뷰 델리게이트 구현이 표준적입니다.

셀 dequeue 처리와 감정 선택 로직이 안전하고 깔끔하게 구현되어 있습니다. 뷰모델과의 통신도 적절합니다.


123-129: 컬렉션뷰 델리게이트 구현이 적절합니다.

사용자 선택을 뷰모델로 전달하는 로직이 명확하고 적절합니다.


131-145: 데이터소스 구현이 안전하게 되었습니다.

옵셔널 바인딩을 통한 안전한 셀 캐스팅과 EmotionType.allCases 활용이 좋습니다.

Comment on lines +108 to +120
override func bind() {
viewModel.output.registerEmotionResultPublisher
.receive(on: DispatchQueue.main)
.sink { [weak self] registerEmotionResult in
if registerEmotionResult {
// TODO: 추천 루틴 화면 보여주기
BitnagilLogger.log(logType: .error, message: "감정 등록 성공")
} else {
BitnagilLogger.log(logType: .error, message: "감정 등록 실패")
}
}
.store(in: &cancellables)
}
Copy link
Copy Markdown

@coderabbitai coderabbitai bot Jul 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

바인딩 구조는 좋지만 로그 레벨 수정 필요.

Combine 사용과 메모리 관리가 적절하게 구현되어 있습니다. 다만 성공 케이스에서 .error 로그 레벨을 사용하는 것은 부적절합니다.

                if registerEmotionResult {
                    // TODO: 추천 루틴 화면 보여주기
-                    BitnagilLogger.log(logType: .error, message: "감정 등록 성공")
+                    BitnagilLogger.log(logType: .info, message: "감정 등록 성공")
                } else {
                    BitnagilLogger.log(logType: .error, message: "감정 등록 실패")
                }
🧰 Tools
🪛 SwiftLint (0.57.0)

[Warning] 113-113: TODOs should be resolved (추천 루틴 화면 보여주기)

(todo)

🤖 Prompt for AI Agents
In Projects/Presentation/Sources/EmotionRegister/View/EmotionRegisterView.swift
between lines 108 and 120, the log level for the success case is incorrectly set
to .error. Change the log level in the success branch from .error to a more
appropriate level such as .info or .debug to accurately reflect the successful
emotion registration event.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

허얼 ~~ 이건 완전 밑에 로그 복붙하느라 생긴 실수인데 !!! 어차피 서버 로직 붙이면서 삭제 혹은 교체될 예정이라 다음 PR에 반영하겠습니다 ㅜ.ㅜ

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@choijungp 네, 이해했습니다! 복붙 실수로 생긴 거였군요 😄 서버 로직 붙이시면서 정리하시면 되겠습니다. 현재는 임시 코드니까 다음 PR에서 처리하시는 게 합리적이네요!


🧠 Learnings used
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 호출하는 것이 적절한 이유: 사용자가 이전 페이지에서 온보딩 선택지를 변경한 후 돌아올 때 새로운 선택지로 다시 등록해야 하기 때문. 홈 뷰에서는 이 뷰로 돌아올 수 없어서 중복 호출 문제가 발생하지 않음.

Learnt from: choijungp
PR: YAPP-Github/Bitnagil-iOS#19
File: Projects/Presentation/Sources/Login/View/TermsAgreementView.swift:44-46
Timestamp: 2025-07-16T09:09:13.869Z
Learning: BaseViewController의 viewDidLoad() 메서드에서 이미 configureAttribute(), configureLayout(), bind()를 호출하므로, 하위 클래스에서 super.viewDidLoad()를 호출하면 이 메서드들이 자동으로 호출된다. 따라서 하위 클래스에서 추가로 호출할 필요가 없다.

Learnt from: choijungp
PR: YAPP-Github/Bitnagil-iOS#19
File: Projects/Presentation/Sources/Login/View/TermsAgreementView.swift:44-46
Timestamp: 2025-07-16T09:09:13.869Z
Learning: BaseViewController의 viewDidLoad() 메서드에서 이미 configureAttribute(), configureLayout(), bind()를 호출하므로, 하위 클래스에서 super.viewDidLoad()를 호출하면 이 메서드들이 자동으로 호출된다. 따라서 하위 클래스에서 추가로 호출할 필요가 없다.

Learnt from: choijungp
PR: YAPP-Github/Bitnagil-iOS#19
File: Projects/Domain/Sources/UseCase/Onboarding/OnboardingUseCase.swift:0-0
Timestamp: 2025-07-16T10:58:30.858Z
Learning: choijungp는 OnboardingUseCase의 convertToDictionary 함수에서 에러 처리 개선을 추후 고민하고 반영할 계획을 가지고 있음.

Learnt from: choijungp
PR: YAPP-Github/Bitnagil-iOS#19
File: Projects/Presentation/Sources/Common/PresentationDependencyAssembler.swift:0-0
Timestamp: 2025-07-16T10:57:16.559Z
Learning: choijungp는 추후 CustomAlertView를 만들어서 에러 처리를 UI로 해결하도록 수정할 계획을 가지고 있음.

Comment on lines +108 to +121
override func bind() {
viewModel.output.registerEmotionResultPublisher
.receive(on: DispatchQueue.main)
.sink { [weak self] registerEmotionResult in
if registerEmotionResult {
// TODO: 추천 루틴 화면 보여주기
BitnagilLogger.log(logType: .error, message: "감정 등록 성공")
} else {
BitnagilLogger.log(logType: .error, message: "감정 등록 실패")
}
}
.store(in: &cancellables)
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

로그 타입과 화면 전환 로직을 개선해주세요.

두 가지 개선사항이 있습니다:

  1. 성공 케이스에서 .error 로그 타입을 사용하고 있습니다
  2. TODO로 표시된 화면 전환 로직이 필요합니다
                if registerEmotionResult {
                    // TODO: 추천 루틴 화면 보여주기
-                    BitnagilLogger.log(logType: .error, message: "감정 등록 성공")
+                    BitnagilLogger.log(logType: .info, message: "감정 등록 성공")
                } else {
                    BitnagilLogger.log(logType: .error, message: "감정 등록 실패")
                }

화면 전환 로직 구현이나 이슈 등록에 도움이 필요하시면 말씀해 주세요.

🧰 Tools
🪛 SwiftLint (0.57.0)

[Warning] 113-113: TODOs should be resolved (추천 루틴 화면 보여주기)

(todo)

🤖 Prompt for AI Agents
In Projects/Presentation/Sources/EmotionRegister/View/EmotionRegisterView.swift
around lines 108 to 121, change the log type for the success case from .error to
a more appropriate level like .info or .debug. Additionally, replace the TODO
comment with the actual screen transition logic to show the recommendation
routine screen upon successful emotion registration. If the transition requires
navigation or presenting a new view controller, implement that accordingly.

@taipaise
Copy link
Copy Markdown
Collaborator

너무 너무 깔끔합니다!!! 코리 없이 머지해도 될 정도 👍👍 오늘도 고생하셨습니다~!


private let mainLabel = UILabel()
private let subLabel = UILabel()
private var emotionOrbCollectionView: UICollectionView = {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

호옥시 요 component만 var로 선언한 이유가 있을까요???

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

헐 !!! UICollectionViewFlowLayout를 밑에 configureAttribute 함수에서 넣어주려고 var로 선언했다가 , ...
초기화 당시에 지정해주지 않으면 에러가 나서 .. 저장 프로퍼티로 바꿨는데 !! let 수정을 안했서요 !!!

예리 띵동 .. 바로 수정하고 머지할게요 !!!!! 감사합니다 !!!!!!!! 🥺👍🏻

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
Projects/Presentation/Sources/EmotionRegister/View/EmotionRegisterView.swift (1)

108-121: 이전 리뷰에서 언급된 로그 타입 이슈가 여전히 남아있습니다.

성공 케이스에서 .error 로그 타입을 사용하는 문제와 TODO 주석이 남아있습니다. 개발자가 다음 PR에서 서버 로직과 함께 해결하겠다고 하신 부분이지만, 일관성을 위해 다시 언급합니다.

                if registerEmotionResult {
                    // TODO: 추천 루틴 화면 보여주기
-                    BitnagilLogger.log(logType: .error, message: "감정 등록 성공")
+                    BitnagilLogger.log(logType: .info, message: "감정 등록 성공")
                } else {
                    BitnagilLogger.log(logType: .error, message: "감정 등록 실패")
                }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 799db5d and c7b64c3.

📒 Files selected for processing (1)
  • Projects/Presentation/Sources/EmotionRegister/View/EmotionRegisterView.swift (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: choijungp
PR: YAPP-Github/Bitnagil-iOS#19
File: Projects/Presentation/Sources/Common/PresentationDependencyAssembler.swift:0-0
Timestamp: 2025-07-16T10:57:16.559Z
Learning: choijungp는 추후 CustomAlertView를 만들어서 에러 처리를 UI로 해결하도록 수정할 계획을 가지고 있음.
Learnt from: choijungp
PR: YAPP-Github/Bitnagil-iOS#19
File: Projects/Domain/Sources/UseCase/Onboarding/OnboardingUseCase.swift:0-0
Timestamp: 2025-07-16T10:58:30.858Z
Learning: choijungp는 OnboardingUseCase의 convertToDictionary 함수에서 에러 처리 개선을 추후 고민하고 반영할 계획을 가지고 있음.
Projects/Presentation/Sources/EmotionRegister/View/EmotionRegisterView.swift (5)

Learnt from: choijungp
PR: #19
File: Projects/Domain/Sources/UseCase/Onboarding/OnboardingUseCase.swift:0-0
Timestamp: 2025-07-16T10:58:30.858Z
Learning: choijungp는 OnboardingUseCase의 convertToDictionary 함수에서 에러 처리 개선을 추후 고민하고 반영할 계획을 가지고 있음.

Learnt from: choijungp
PR: #19
File: Projects/Presentation/Sources/Onboarding/View/OnboardingRecommendedRoutineView.swift:57-59
Timestamp: 2025-07-16T09:21:15.038Z
Learning: OnboardingRecommendedRoutineView에서 viewWillAppear에 registerOnboarding 호출하는 것이 적절한 이유: 사용자가 이전 페이지에서 온보딩 선택지를 변경한 후 돌아올 때 새로운 선택지로 다시 등록해야 하기 때문. 홈 뷰에서는 이 뷰로 돌아올 수 없어서 중복 호출 문제가 발생하지 않음.

Learnt from: choijungp
PR: #19
File: Projects/Presentation/Sources/Common/PresentationDependencyAssembler.swift:0-0
Timestamp: 2025-07-16T10:57:16.559Z
Learning: choijungp는 추후 CustomAlertView를 만들어서 에러 처리를 UI로 해결하도록 수정할 계획을 가지고 있음.

Learnt from: choijungp
PR: #19
File: Projects/Presentation/Sources/Login/View/TermsAgreementView.swift:44-46
Timestamp: 2025-07-16T09:09:13.869Z
Learning: BaseViewController의 viewDidLoad() 메서드에서 이미 configureAttribute(), configureLayout(), bind()를 호출하므로, 하위 클래스에서 super.viewDidLoad()를 호출하면 이 메서드들이 자동으로 호출된다. 따라서 하위 클래스에서 추가로 호출할 필요가 없다.

Learnt from: choijungp
PR: #19
File: Projects/Presentation/Sources/Login/View/TermsAgreementView.swift:44-46
Timestamp: 2025-07-16T09:09:13.869Z
Learning: BaseViewController의 viewDidLoad() 메서드에서 이미 configureAttribute(), configureLayout(), bind()를 호출하므로, 하위 클래스에서 super.viewDidLoad()를 호출하면 이 메서드들이 자동으로 호출된다. 따라서 하위 클래스에서 추가로 호출할 필요가 없다.

🪛 SwiftLint (0.57.0)
Projects/Presentation/Sources/EmotionRegister/View/EmotionRegisterView.swift

[Warning] 113-113: TODOs should be resolved (추천 루틴 화면 보여주기)

(todo)


[Warning] 53-53: Remove overridden functions that don't do anything except call their super

(unneeded_override)

🔇 Additional comments (8)
Projects/Presentation/Sources/EmotionRegister/View/EmotionRegisterView.swift (8)

8-13: 클래스 구조와 import가 적절합니다.

BaseViewController를 상속받은 MVVM 패턴 구현이 올바르게 되어 있고, 필요한 모듈들이 적절히 import되어 있습니다.


15-27: 레이아웃 상수 구조가 잘 정리되어 있습니다.

private enum을 사용한 레이아웃 상수 관리 방식이 좋고, 네이밍도 명확합니다.


29-42: UI 컴포넌트 구조가 적절합니다.

클로저를 사용한 컬렉션뷰 초기화 패턴이 좋고, FlowLayout 설정도 적절합니다. Combine을 위한 cancellables 프로퍼티도 올바르게 포함되어 있습니다.


44-51: 초기화 메서드가 올바르게 구현되어 있습니다.

cancellables 초기화와 super 호출이 적절하고, 스토리보드를 지원하지 않는 뷰컨트롤러의 표준 패턴을 따르고 있습니다.


57-60: 네비게이션 바 설정이 적절합니다.

viewWillAppear에서 백 버튼이 있는 네비게이션 스타일을 설정하는 것이 올바릅니다.


62-78: UI 속성 설정이 잘 구현되어 있습니다.

레이블 텍스트, 폰트, 색상 설정이 디자인 시스템을 활용해 일관성 있게 구현되었고, 컬렉션뷰 설정도 적절합니다.


80-106: 레이아웃 구성이 체계적으로 잘 되어 있습니다.

SnapKit을 사용한 제약조건 설정이 명확하고, 사전 정의된 Layout 상수를 활용한 것이 좋습니다. Safe Area를 적절히 활용하고 있습니다.


131-145: 컬렉션뷰 데이터소스 구현이 안전하고 올바릅니다.

guard 문을 사용한 타입 안전성 확보와 EmotionType.allCases를 활용한 데이터 구성이 적절합니다. 셀 구성 로직도 명확합니다.

Comment on lines +53 to +55
override func viewDidLoad() {
super.viewDidLoad()
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

불필요한 viewDidLoad 오버라이드를 제거해주세요.

BaseViewController의 viewDidLoad()에서 이미 configureAttribute(), configureLayout(), bind()를 호출하므로, 단순히 super를 호출하는 오버라이드는 불필요합니다.

-    override func viewDidLoad() {
-        super.viewDidLoad()
-    }
-
📝 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.

Suggested change
override func viewDidLoad() {
super.viewDidLoad()
}
🧰 Tools
🪛 SwiftLint (0.57.0)

[Warning] 53-53: Remove overridden functions that don't do anything except call their super

(unneeded_override)

🤖 Prompt for AI Agents
In Projects/Presentation/Sources/EmotionRegister/View/EmotionRegisterView.swift
at lines 53 to 55, the viewDidLoad() method is overridden only to call
super.viewDidLoad(), which is unnecessary because the BaseViewController already
calls configureAttribute(), configureLayout(), and bind() in its viewDidLoad().
Remove this empty override of viewDidLoad() to clean up the code.

@choijungp choijungp merged commit 486323b into develop Jul 28, 2025
2 checks passed
@choijungp choijungp deleted the feat/emotionRegister branch July 28, 2025 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants