Skip to content

Conversation

@leejh08
Copy link
Member

@leejh08 leejh08 commented Dec 25, 2025

๊ฐœ์š”

  • ๋งˆ์ดํŽ˜์ด์ง€ ์ƒ์„ธ ReactorKit

์ž‘์—…์‚ฌํ•ญ

  • ๋งˆ์ดํŽ˜์ด์ง€ ์ƒ์„ธ ReactorKit

UI

Summary by CodeRabbit

๋ฆด๋ฆฌ์Šค ๋…ธํŠธ

New Features

  • ๋ฒ„๊ทธ ๋ฆฌํฌํŠธ: ๋ฆฌ์•กํ„ฐ ๊ธฐ๋ฐ˜ ์ œ์ถœ ํ๋ฆ„ ๋„์ž… โ€” ์ด๋ฏธ์ง€ ์ฒจ๋ถ€ ์ „์†ก, ์ œ์ถœ ์™„๋ฃŒ ํ† ์ŠคํŠธ ๋ฐ ์ž๋™ ๋’ค๋กœ๊ฐ€๊ธฐ ๋ฐ˜์˜. ์ฃผ์š” ๋ถ„๋ฅ˜ ์„ ํƒ์ด ์ƒํƒœ๋กœ ์—ฐ๋™๋˜์–ด UI ๋™๊ธฐํ™” ๊ฐœ์„ .
  • ๊ด€์‹ฌ ๋ถ„์•ผ: ์„ ํƒ ํ™”๋ฉด์—์„œ ์ž๋™ ๋ฃจํŠธ ๋ณต๊ท€ ๊ธฐ๋Šฅ ์ถ”๊ฐ€.

Refactor

  • ์•Œ๋ฆผ ์„ค์ •ยท๋ฒ„๊ทธ ๋ฆฌํฌํŠธยท๊ด€์‹ฌ ๋ถ„์•ผ ์ „์ฒด๋ฅผ ๋ฆฌ์•กํ„ฐ(์ƒํƒœ ์ค‘์‹ฌ) ์•„ํ‚คํ…์ฒ˜๋กœ ์ „ํ™˜ํ•ด UI ๋ฐ”์ธ๋”ฉ๊ณผ ๋‚ด๋น„๊ฒŒ์ด์…˜ ์ผ๊ด€์„ฑ ํ–ฅ์ƒ.

Other

  • ๊ฐœ๋ฐœ ์œ ํ˜•์— ๋Œ€ํ•ด ๋กœ์ปฌ ๋ฌธ๊ตฌ๋กœ๋ถ€ํ„ฐ ์ƒ์„ฑ ๊ฐ€๋Šฅํ•œ ์ดˆ๊ธฐํ™” ๊ธฐ๋Šฅ ์ถ”๊ฐ€.

โœ๏ธ Tip: You can customize this high-level summary in your review settings.

@leejh08 leejh08 requested a review from circle0802 December 25, 2025 13:12
@leejh08 leejh08 self-assigned this Dec 25, 2025
@leejh08 leejh08 added the โ™ป๏ธrefactor ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง ํ•  ๊ฒฝ์šฐ label Dec 25, 2025
@coderabbitai
Copy link

coderabbitai bot commented Dec 25, 2025

Walkthrough

MyPage์˜ BugReport, InterestField(๋ฐ Check), NotificationSetting ๋ชจ๋“ˆ์„ MVVM(ViewModel)์—์„œ ReactorKit(Reactor) ๊ธฐ๋ฐ˜์œผ๋กœ ์ „๋ฉด ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด ViewModel ํŒŒ์ผ ์‚ญ์ œ, ๋Œ€์‘ Reactor ์ถ”๊ฐ€, ViewController/Flow/DI์—์„œ viewModel ์ฐธ์กฐ๋ฅผ reactor๋กœ ๊ต์ฒดํ–ˆ์Šต๋‹ˆ๋‹ค.

Changes

์‘์ง‘๋„ / ํŒŒ์ผ(๋“ค) ๋ณ€๊ฒฝ ๋‚ด์šฉ ์š”์•ฝ
BugReport
Projects/Presentation/Sources/BugReport/BugReportReactor.swift, Projects/Presentation/Sources/BugReport/BugReportViewController.swift, Projects/Presentation/Sources/BugReport/BugReportViewModel.swift, Projects/Flow/Sources/MyPage/BugReport/BugReportFlow.swift
BugReportReactor ์ถ”๊ฐ€(์•ก์…˜/๋ฎคํ…Œ์ด์…˜/์ƒํƒœ), ViewController๋ฅผ BaseReactorViewController<BugReportReactor>๋กœ ์ „ํ™˜, ๊ธฐ์กด BugReportViewModel ์‚ญ์ œ, Flow์—์„œ rootViewController.reactor ์‚ฌ์šฉ์œผ๋กœ ๋ณ€๊ฒฝ
InterestField
Projects/Presentation/Sources/InterestField/InterestFieldReactor.swift, Projects/Presentation/Sources/InterestField/InterestFieldViewController.swift, Projects/Presentation/Sources/InterestField/InterestFieldViewModel.swift, Projects/Flow/Sources/MyPage/InterestField/InterestFieldFlow.swift
InterestFieldReactor ์ถ”๊ฐ€, ViewController๋ฅผ Reactor ๊ธฐ๋ฐ˜์œผ๋กœ ๋ณ€๊ฒฝ, ๊ธฐ์กด ViewModel ์‚ญ์ œ, ์„ ํƒ/์ƒํƒœ ๋กœ์ง์„ reactor.state๋กœ ์ด์ „, Flow์—์„œ .popHomeFieldIsRequired ์ฒ˜๋ฆฌ ๋ฐ popToMyPage() ๋„์ž…
InterestFieldCheck
Projects/Presentation/Sources/InterestField/InterestFieldCheckReactor.swift, Projects/Presentation/Sources/InterestField/InterestFieldCheckViewController.swift, Projects/Presentation/Sources/InterestField/InterestFieldCheckViewModel.swift, Projects/Flow/Sources/MyPage/InterestField/InterestFieldCheckFlow.swift
InterestFieldCheckReactor ์ถ”๊ฐ€(ํ•™์ƒ์ •๋ณด ์กฐํšŒ, ์ž๋™ ๋„ค๋น„๊ฒŒ์ด์…˜ ํƒ€์ด๋จธ), ViewController๋ฅผ Reactor ๊ธฐ๋ฐ˜์œผ๋กœ ๋ณ€๊ฒฝ, ๊ธฐ์กด ViewModel ์‚ญ์ œ, Flow์—์„œ ๋ฃจํŠธ ํŒ ์ฒ˜๋ฆฌ ์ถ”๊ฐ€
NotificationSetting
Projects/Presentation/Sources/NotificationSetting/NotificationSettingReactor.swift, Projects/Presentation/Sources/NotificationSetting/NotificationSettingViewController.swift, Projects/Presentation/Sources/NotificationSetting/NotificationSettingViewModel.swift, Projects/Flow/Sources/MyPage/Notification/NotificationSettingFlow.swift
NotificationSettingReactor ์ถ”๊ฐ€, ViewController๋ฅผ Reactor ๊ธฐ๋ฐ˜์œผ๋กœ ๋ณ€๊ฒฝ, ๊ธฐ์กด ViewModel ์‚ญ์ œ, Flow์—์„œ next-step ์Šคํ…Œํผ๋ฅผ reactor๋กœ ์ „ํ™˜
DI ์–ด์…ˆ๋ธ”๋ฆฌ
Projects/Presentation/Sources/DI/Assembly/SettingPresentationAssembly.swift
Presentation DI ๋“ฑ๋ก/ํ•ด๊ฒฐ์„ ViewModel โ†’ Reactor๋กœ ๊ต์ฒด (Notification/BugReport/InterestField/InterestFieldCheck)
๋„๋ฉ”์ธ ์œ ํ‹ธ
Projects/Domain/Sources/Enums/DevelopmentType.swift
๊ฐœ๋ฐœ ์˜์—ญ enum์— init?(localizedString:) failable ์ด๋‹ˆ์…œ๋ผ์ด์ € ์ถ”๊ฐ€

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant User as ์‚ฌ์šฉ์ž (UI)
    participant VC as ViewController
    participant Reactor as Reactor
    participant UseCase as UseCase
    participant Flow as Flow(Stepper)

    rect rgb(245,250,255)
    Note right of VC: bindAction / bindState
    end

    User->>VC: UI ์ด๋ฒคํŠธ (์˜ˆ: ์ œ์ถœ/ํ† ๊ธ€/์„ ํƒ)
    VC->>Reactor: action (์˜ˆ: bugReportButtonDidTap / toggleNotification / selectButtonDidTap)
    Reactor->>UseCase: execute / ์š”์ฒญ (๋„คํŠธ์›Œํฌ/๋„๋ฉ”์ธ ์ž‘์—…)
    UseCase-->>Reactor: ๊ฒฐ๊ณผ(์„ฑ๊ณต/์‹คํŒจ)
    alt ์„ฑ๊ณต
      Reactor->>Reactor: emit Mutation -> state ์—…๋ฐ์ดํŠธ
      Reactor->>Flow: steps.emit(๋„ค๋น„๊ฒŒ์ด์…˜ ์Šคํ…)  %% ๊ฐ•์กฐ๋œ ์ƒˆ ์ƒํ˜ธ์ž‘์šฉ
    else ์‹คํŒจ
      Reactor->>Reactor: emit ์‹คํŒจ ๊ด€๋ จ Mutation -> state ์—…๋ฐ์ดํŠธ
    end
    Reactor->>VC: state ๋ณ€๊ฒฝ (bindState๋กœ UI ๋ฐ˜์˜)
Loading

Estimated code review effort

๐ŸŽฏ 4 (Complex) | โฑ๏ธ ~45๋ถ„

Possibly related issues

Possibly related PRs

(์ตœ๋Œ€ 3๊ฐœ๋กœ ์ œํ•œ)

Suggested reviewers

  • circle0802
  • cyj513

Poem

๐Ÿฐ ๋ฒ„ํŠผ์„ ํƒญํ•˜๋‹ˆ Reactor๊ฐ€ ๊นก์ถฉ,
State๊ฐ€ ์ถค์ถ”๊ณ  UI๊ฐ€ ๋ฐ˜์ง,
ViewModel์€ ์‰ฌ๋Ÿฌ ๊ฐ€๊ณ  ์šฐ๋ฆฌ๋Š” ์ „์ง„,
๋ณ€๊ฒฝ์˜ ๋‹น๊ทผ์„ ๋ƒ ๋ƒ  ๋จน์œผ๋ฉฐ ์ถ•ํ•˜ํ•˜๋„ค ๐Ÿฅ•โœจ

Pre-merge checks and finishing touches

โŒ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage โš ๏ธ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
โœ… Passed checks (2 passed)
Check name Status Explanation
Description Check โœ… Passed Check skipped - CodeRabbitโ€™s high-level summary is enabled.
Title check โœ… Passed PR ์ œ๋ชฉ์ด ๋งˆ์ดํŽ˜์ด์ง€ ์ƒ์„ธ ํ™”๋ฉด์„ ReactorKit์œผ๋กœ ๋ฆฌํŒฉํ„ฐ๋งํ•œ๋‹ค๋Š” ์ฃผ์š” ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ๋ฐ˜์˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
โœจ Finishing touches
  • ๐Ÿ“ Generate docstrings
๐Ÿงช Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/(#379)-Mypage_Detail_Refactoring

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

All File Checked โœ…

โœ… Auto Pull Request SwiftLint Success!!!!

Copy link

@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: 4

Caution

Some comments are outside the diff and canโ€™t be posted inline due to platform limitations.

โš ๏ธ Outside diff range comments (1)
Projects/Presentation/Sources/NotificationSetting/NotificationSettingViewController.swift (1)

164-172: ์ค‘๋ณต๋œ UI ์—…๋ฐ์ดํŠธ ๋กœ์ง์œผ๋กœ ์ธํ•œ ์ž ์žฌ์  ์ถฉ๋Œ

configureViewController()์—์„œ allNotificationSwitchView.clickSwitchButton์„ ๊ตฌ๋…ํ•˜์—ฌ ๋ชจ๋“  ์Šค์œ„์น˜ ๋ทฐ๋ฅผ ์ง์ ‘ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ bindState()(Lines 128-161)์—์„œ๋„ reactor state ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฐ ์Šค์œ„์น˜ ๋ทฐ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ์žˆ์–ด, ๋‘ ๋กœ์ง์ด ๋™์‹œ์— ๋™์ž‘ํ•˜๋ฉด์„œ UI ์ƒํƒœ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Reactor ํŒจํ„ด์—์„œ๋Š” ๋ชจ๋“  UI ์—…๋ฐ์ดํŠธ๊ฐ€ state๋ฅผ ํ†ตํ•ด ์ด๋ฃจ์–ด์ ธ์•ผ ํ•˜๋ฏ€๋กœ, ์ด ์ง์ ‘ ์—…๋ฐ์ดํŠธ ๋กœ์ง์€ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๐Ÿ”Ž ์ค‘๋ณต ๋กœ์ง ์ œ๊ฑฐ ์ œ์•ˆ
     public override func configureViewController() {
-        allNotificationSwitchView.clickSwitchButton
-            .asObservable()
-            .bind(onNext: { [weak self] isOn in
-                self?.switchViewArray.forEach {
-                    $0.setup(isOn: isOn)
-                }
-            }).disposed(by: disposeBag)
     }
๐Ÿงน Nitpick comments (10)
Projects/Flow/Sources/MyPage/InterestField/InterestFieldFlow.swift (1)

28-34: InterestFieldCheckStep ์ผ€์ด์Šค ์ฒ˜๋ฆฌ๊ฐ€ ๋ช…์‹œ์ ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

default ์ผ€์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‚˜์ค‘์— InterestFieldCheckStep์— ์ƒˆ๋กœ์šด ์ผ€์ด์Šค๊ฐ€ ์ถ”๊ฐ€๋  ๋•Œ ์ปดํŒŒ์ผ๋Ÿฌ ๊ฒฝ๊ณ  ์—†์ด .none์œผ๋กœ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์ผ€์ด์Šค๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋ฉด ํ–ฅํ›„ ์œ ์ง€๋ณด์ˆ˜์— ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

๐Ÿ”Ž ๋ช…์‹œ์  ์ผ€์ด์Šค ์ฒ˜๋ฆฌ ์ œ์•ˆ
 } else if let step = step as? InterestFieldCheckStep {
     switch step {
     case .popHomeFieldIsRequired:
         return popToMyPage()
-    default:
+    case .interestFieldIsRequired, .interestFieldCheckIsRequired:
         return .none
     }
 }
Projects/Flow/Sources/MyPage/InterestField/InterestFieldCheckFlow.swift (1)

58-61: popToMyPage() ํ•จ์ˆ˜๊ฐ€ InterestFieldFlow.swift์™€ ์ค‘๋ณต๋ฉ๋‹ˆ๋‹ค.

๋™์ผํ•œ ๊ตฌํ˜„์ด ๋‘ Flow ํŒŒ์ผ์— ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ๊ณตํ†ต ํ™•์žฅ์ด๋‚˜ ํ”„๋กœํ† ์ฝœ๋กœ ์ถ”์ถœํ•˜๋ฉด ์ฝ”๋“œ ์ค‘๋ณต์„ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ, Flow ๊ฐ„ ๋…๋ฆฝ์„ฑ์„ ์œ„ํ•ด ์˜๋„์ ์œผ๋กœ ๋ถ„๋ฆฌํ•œ ๊ฒƒ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Projects/Presentation/Sources/InterestField/InterestFieldCheckViewController.swift (1)

12-15: ์ฃผ์„ ์ฒ˜๋ฆฌ๋œ ์ฝ”๋“œ๋ฅผ ์ •๋ฆฌํ•ด ์ฃผ์„ธ์š”.

backButton ๊ด€๋ จ ์ฝ”๋“œ๊ฐ€ ์ฃผ์„ ์ฒ˜๋ฆฌ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋” ์ด์ƒ ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค๋ฉด ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ด ์ฝ”๋“œ ๊ฐ€๋…์„ฑ์„ ๋†’์ž…๋‹ˆ๋‹ค.

Also applies to: 20-21, 29-33

Projects/Presentation/Sources/InterestField/InterestFieldViewController.swift (1)

105-116: ์…€ ๊ตฌ์„ฑ ์‹œ reactor.currentState ์ ‘๊ทผ์— ์ฃผ์˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

rx.items ํด๋กœ์ € ๋‚ด์—์„œ reactor.currentState.selectedInterests์— ์ ‘๊ทผํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํด๋กœ์ €๋Š” availableInterests๊ฐ€ emit๋  ๋•Œ ํ˜ธ์ถœ๋˜์ง€๋งŒ, selectedInterests๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด๋„ ์…€์ด ์ž๋™์œผ๋กœ ์—…๋ฐ์ดํŠธ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Lines 143-149์˜ reloadData() ํ˜ธ์ถœ๋กœ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ณ  ์žˆ์ง€๋งŒ, combineLatest๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋” ๋ฐ˜์‘์ ์ธ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ”Ž combineLatest ์‚ฌ์šฉ ์ œ์•ˆ
Observable.combineLatest(
    reactor.state.map { $0.availableInterests },
    reactor.state.map { $0.selectedInterests }
)
.bind(to: majorCollectionView.rx.items(...)) { index, (codeEntity, selectedInterests), cell in
    // ...
}
Projects/Presentation/Sources/BugReport/BugReportViewController.swift (1)

11-12: ์ด๋ฏธ์ง€ ์ƒํƒœ๋ฅผ Reactor๋กœ ์ด๋™ํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด ์ฃผ์„ธ์š”.

imageStringList์™€ imageList๊ฐ€ ViewController์˜ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋กœ ๊ด€๋ฆฌ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ReactorKit ํŒจํ„ด์—์„œ๋Š” ์ƒํƒœ๋ฅผ Reactor์˜ State์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ผ๊ด€์„ฑ ์žˆ๋Š” ๋‹จ๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ์œ ์ง€ํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

Projects/Presentation/Sources/InterestField/InterestFieldCheckReactor.swift (1)

35-38: fetchStudentInfo ์•ก์…˜์—์„œ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ˆ„๋ฝ

fetchStudentInfoUseCase.execute()๊ฐ€ ์‹คํŒจํ•  ๊ฒฝ์šฐ ์—๋Ÿฌ๊ฐ€ ์ „ํŒŒ๋˜์–ด ์ŠคํŠธ๋ฆผ์ด ์ข…๋ฃŒ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. catchAndReturn ๋˜๋Š” catchErrorJustComplete๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—๋Ÿฌ๋ฅผ ์ ์ ˆํžˆ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ”Ž ์—๋Ÿฌ ์ฒ˜๋ฆฌ ์ถ”๊ฐ€ ์ œ์•ˆ
         case .fetchStudentInfo:
             return fetchStudentInfoUseCase.execute()
                 .asObservable()
                 .map { .setStudentName($0.studentName) }
+                .catch { _ in .empty() }
Projects/Presentation/Sources/DI/Assembly/SettingPresentationAssembly.swift (1)

81-88: ๋“ฑ๋ก ์ˆœ์„œ ๊ฐœ์„  ์ œ์•ˆ

BugReportViewController๊ฐ€ BugReportReactor๋ณด๋‹ค ๋จผ์ € ๋“ฑ๋ก๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€๋…์„ฑ์„ ์œ„ํ•ด ์˜์กด์„ฑ(Reactor)์„ ๋จผ์ € ๋“ฑ๋กํ•˜๊ณ  ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ViewController๋ฅผ ์ดํ›„์— ๋“ฑ๋กํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๐Ÿ”Ž ๋“ฑ๋ก ์ˆœ์„œ ๋ณ€๊ฒฝ ์ œ์•ˆ
         // Bug Report
+        container.register(BugReportReactor.self) { resolver in
+            BugReportReactor(
+                reportBugUseCase: resolver.resolve(ReportBugUseCase.self)!
+            )
+        }
         container.register(BugReportViewController.self) { resolver in
             BugReportViewController(resolver.resolve(BugReportReactor.self)!)
         }
-        container.register(BugReportReactor.self) { resolver in
-            BugReportReactor(
-                reportBugUseCase: resolver.resolve(ReportBugUseCase.self)!
-            )
-        }
Projects/Presentation/Sources/InterestField/InterestFieldReactor.swift (2)

52-65: fetchInterestFields์—์„œ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ˆ„๋ฝ

fetchCodeListUseCase์™€ fetchStudentInfoUseCase ํ˜ธ์ถœ ์‹œ ์—๋Ÿฌ ์ฒ˜๋ฆฌ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋„คํŠธ์›Œํฌ ์‹คํŒจ ์‹œ ์ŠคํŠธ๋ฆผ์ด ์ข…๋ฃŒ๋˜์–ด ์ดํ›„ ์•ก์…˜์ด ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ”Ž ์—๋Ÿฌ ์ฒ˜๋ฆฌ ์ถ”๊ฐ€ ์ œ์•ˆ
         case .fetchInterestFields:
             let interests = fetchCodeListUseCase.execute(
                 keyword: nil,
                 type: .job,
                 parentCode: nil
             )
             .asObservable()
             .map { Mutation.setAvailableInterests($0) }
+            .catch { _ in .empty() }

             let studentInfo = fetchStudentInfoUseCase.execute()
                 .asObservable()
                 .map { Mutation.setStudentName($0.studentName) }
+                .catch { _ in .empty() }

             return .merge(interests, studentInfo)

70-78: selectButtonDidTap ์•ก์…˜์—์„œ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ˆ„๋ฝ

changeInterestsUseCase.execute()๊ฐ€ ์‹คํŒจํ•  ๊ฒฝ์šฐ ์‚ฌ์šฉ์ž์—๊ฒŒ ํ”ผ๋“œ๋ฐฑ ์—†์ด ์‹คํŒจํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—๋Ÿฌ ์ƒํƒœ๋ฅผ State์— ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜, ์ตœ์†Œํ•œ ์—๋Ÿฌ๋ฅผ ๋กœ๊น…ํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ”Ž ์—๋Ÿฌ ์ฒ˜๋ฆฌ ์ถ”๊ฐ€ ์ œ์•ˆ
         case .selectButtonDidTap:
             let codeIDs = currentState.selectedInterests.map { $0.code }
             return changeInterestsUseCase.execute(codeIDs: codeIDs)
                 .asObservable()
                 .do(onCompleted: { [weak self] in
                     self?.steps.accept(InterestFieldStep.interestFieldCheckIsRequired)
                 })
                 .flatMap { _ in Observable<Mutation>.empty() }
+                .catch { _ in .empty() }
Projects/Presentation/Sources/NotificationSetting/NotificationSettingReactor.swift (1)

61-86: mutate ํ•จ์ˆ˜์—์„œ ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ˆ„๋ฝ

fetchSubscribeStateUseCase, subscribeNotificationUseCase, subscribeAllNotificationUseCase ํ˜ธ์ถœ ์‹œ ์—๋Ÿฌ ์ฒ˜๋ฆฌ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋„คํŠธ์›Œํฌ ์‹คํŒจ ์‹œ ์ ์ ˆํ•œ ์‚ฌ์šฉ์ž ํ”ผ๋“œ๋ฐฑ์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ”Ž ์—๋Ÿฌ ์ฒ˜๋ฆฌ ์ถ”๊ฐ€ ์˜ˆ์‹œ
         case .fetchNotificationSettings:
             return fetchSubscribeStateUseCase.execute()
                 .asObservable()
                 .map { entities -> [NotificationType: Bool] in
                     var states: [NotificationType: Bool] = [:]
                     entities.forEach { states[$0.topic] = $0.isSubscribed }
                     return states
                 }
                 .map { .setSubscribeStates($0) }
+                .catch { _ in .empty() }
๐Ÿ“œ Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

๐Ÿ“ฅ Commits

Reviewing files that changed from the base of the PR and between b8d06ab and d509d60.

๐Ÿ“’ Files selected for processing (17)
  • Projects/Flow/Sources/MyPage/BugReport/BugReportFlow.swift
  • Projects/Flow/Sources/MyPage/InterestField/InterestFieldCheckFlow.swift
  • Projects/Flow/Sources/MyPage/InterestField/InterestFieldFlow.swift
  • Projects/Flow/Sources/MyPage/Notification/NotificationSettingFlow.swift
  • Projects/Presentation/Sources/BugReport/BugReportReactor.swift
  • Projects/Presentation/Sources/BugReport/BugReportViewController.swift
  • Projects/Presentation/Sources/BugReport/BugReportViewModel.swift
  • Projects/Presentation/Sources/DI/Assembly/SettingPresentationAssembly.swift
  • Projects/Presentation/Sources/InterestField/InterestFieldCheckReactor.swift
  • Projects/Presentation/Sources/InterestField/InterestFieldCheckViewController.swift
  • Projects/Presentation/Sources/InterestField/InterestFieldCheckViewModel.swift
  • Projects/Presentation/Sources/InterestField/InterestFieldReactor.swift
  • Projects/Presentation/Sources/InterestField/InterestFieldViewController.swift
  • Projects/Presentation/Sources/InterestField/InterestFieldViewModel.swift
  • Projects/Presentation/Sources/NotificationSetting/NotificationSettingReactor.swift
  • Projects/Presentation/Sources/NotificationSetting/NotificationSettingViewController.swift
  • Projects/Presentation/Sources/NotificationSetting/NotificationSettingViewModel.swift
๐Ÿ’ค Files with no reviewable changes (4)
  • Projects/Presentation/Sources/NotificationSetting/NotificationSettingViewModel.swift
  • Projects/Presentation/Sources/BugReport/BugReportViewModel.swift
  • Projects/Presentation/Sources/InterestField/InterestFieldViewModel.swift
  • Projects/Presentation/Sources/InterestField/InterestFieldCheckViewModel.swift
๐Ÿงฐ Additional context used
๐Ÿงฌ Code graph analysis (7)
Projects/Presentation/Sources/NotificationSetting/NotificationSettingViewController.swift (1)
Projects/Presentation/Sources/NotificationSetting/Component/NotificationSectionView.swift (1)
  • setup (57-62)
Projects/Presentation/Sources/InterestField/InterestFieldCheckReactor.swift (3)
Projects/Presentation/Sources/InterestField/Components/InterestCheckView.swift (1)
  • setStudentName (57-65)
Projects/Presentation/Sources/InterestField/InterestFieldReactor.swift (2)
  • mutate (50-79)
  • reduce (81-100)
Projects/Presentation/Sources/NotificationSetting/NotificationSettingReactor.swift (2)
  • mutate (61-87)
  • reduce (89-108)
Projects/Presentation/Sources/InterestField/InterestFieldReactor.swift (3)
Projects/Presentation/Sources/InterestField/Components/InterestCheckView.swift (1)
  • setStudentName (57-65)
Projects/Presentation/Sources/InterestField/InterestFieldCheckReactor.swift (2)
  • mutate (33-50)
  • reduce (52-61)
Projects/Presentation/Sources/NotificationSetting/NotificationSettingReactor.swift (2)
  • mutate (61-87)
  • reduce (89-108)
Projects/Flow/Sources/MyPage/InterestField/InterestFieldCheckFlow.swift (1)
Projects/Flow/Sources/MyPage/InterestField/InterestFieldFlow.swift (1)
  • popToMyPage (59-62)
Projects/Presentation/Sources/NotificationSetting/NotificationSettingReactor.swift (1)
Projects/App/Sources/AppDelegate.swift (1)
  • messaging (91-104)
Projects/Presentation/Sources/InterestField/InterestFieldCheckViewController.swift (2)
Projects/Presentation/Sources/InterestField/InterestFieldViewController.swift (2)
  • bindAction (83-102)
  • bindState (104-150)
Projects/Presentation/Sources/NotificationSetting/NotificationSettingViewController.swift (2)
  • bindAction (90-125)
  • bindState (127-162)
Projects/Presentation/Sources/BugReport/BugReportViewController.swift (3)
Projects/Presentation/Sources/MyPage/MyPageViewController.swift (2)
  • bindAction (92-145)
  • bindState (147-165)
Projects/Presentation/Sources/BugReport/MajorBottomSheet/MajorBottomSheetViewController.swift (1)
  • bind (52-58)
Projects/Modules/DesignSystem/Sources/Extensions/UIViewController/UIViewController+showJobisToast.swift (1)
  • showJobisToast (5-33)
โฐ 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). (2)
  • GitHub Check: JOBIS_DSM_iOS | JOBIS v2 CI | Test - iOS
  • GitHub Check: JOBIS_DSM_iOS | JOBIS v2 CI | Build - iOS
๐Ÿ”‡ Additional comments (16)
Projects/Flow/Sources/MyPage/BugReport/BugReportFlow.swift (1)

36-36: ReactorKit ํŒจํ„ด์œผ๋กœ์˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์ด ์ž˜ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

viewModel์—์„œ reactor๋กœ์˜ ์ „ํ™˜์ด ์ผ๊ด€๋˜๊ฒŒ ์ ์šฉ๋˜์—ˆ์œผ๋ฉฐ, steps relay๋ฅผ ํ†ตํ•œ ๋„ค๋น„๊ฒŒ์ด์…˜ ์Šคํ… ์ฒ˜๋ฆฌ ๋ฐฉ์‹์ด ReactorKit์˜ Stepper ํ”„๋กœํ† ์ฝœ๊ณผ ์ž˜ ๋งž์Šต๋‹ˆ๋‹ค.

Also applies to: 45-45

Projects/Presentation/Sources/BugReport/BugReportReactor.swift (1)

37-43: State ํ”„๋กœํผํ‹ฐ์˜ ์ ‘๊ทผ ์ œ์–ด์ž๋ฅผ ํ™•์ธํ•ด ์ฃผ์„ธ์š”.

State struct์˜ ํ”„๋กœํผํ‹ฐ๋“ค์ด internal ์ ‘๊ทผ ์ˆ˜์ค€์ž…๋‹ˆ๋‹ค. ์™ธ๋ถ€ ๋ชจ๋“ˆ์—์„œ reactor.currentState์— ์ ‘๊ทผํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ public์œผ๋กœ ์„ ์–ธํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Projects/Flow/Sources/MyPage/Notification/NotificationSettingFlow.swift (1)

33-33: LGTM!

ReactorKit ํŒจํ„ด์œผ๋กœ์˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Projects/Flow/Sources/MyPage/InterestField/InterestFieldFlow.swift (1)

45-45: Reactor ๊ธฐ๋ฐ˜ stepper๋กœ์˜ ์ „ํ™˜์ด ์ž˜ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

viewModel์—์„œ reactor๋กœ์˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์ด ์ผ๊ด€๋˜๊ฒŒ ์ ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Also applies to: 55-55

Projects/Flow/Sources/MyPage/InterestField/InterestFieldCheckFlow.swift (1)

40-40: LGTM!

Reactor ๊ธฐ๋ฐ˜ stepper๋กœ์˜ ์ „ํ™˜์ด ์ผ๊ด€๋˜๊ฒŒ ์ ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Also applies to: 54-54

Projects/Presentation/Sources/InterestField/InterestFieldCheckViewController.swift (1)

41-61: ReactorKit ๋ฐ”์ธ๋”ฉ ํŒจํ„ด์ด ์ž˜ ์ ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

viewWillAppear์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ fetchํ•˜๊ณ  viewDidAppear์—์„œ ์ž๋™ ๋„ค๋น„๊ฒŒ์ด์…˜์„ ์‹œ์ž‘ํ•˜๋Š” ํŒจํ„ด์ด ๋ช…ํ™•ํ•ฉ๋‹ˆ๋‹ค. State ๋ฐ”์ธ๋”ฉ์—์„œ filter์™€ distinctUntilChanged๋ฅผ ์ ์ ˆํžˆ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Projects/Presentation/Sources/InterestField/InterestFieldViewController.swift (1)

159-162: Safe subscript ํ™•์žฅ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๋ฐฐ์—ด ๋ฒ”์œ„ ์ดˆ๊ณผ ์ ‘๊ทผ์„ ๋ฐฉ์ง€ํ•˜๋Š” ์•ˆ์ „ํ•œ ํŒจํ„ด์ž…๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์ด ํ™•์žฅ์ด ๋‹ค๋ฅธ ๊ณณ์—์„œ๋„ ์‚ฌ์šฉ๋œ๋‹ค๋ฉด Core ๋ชจ๋“ˆ ๋“ฑ ๊ณตํ†ต ์œ„์น˜๋กœ ์ด๋™ํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด ๋ณด์„ธ์š”.

Projects/Presentation/Sources/BugReport/BugReportViewController.swift (1)

169-176: ์ด๋ฏธ์ง€ ๋ฆฌ์ŠคํŠธ ์—…๋ฐ์ดํŠธ์™€ ๋ฒ„ํŠผ ํƒญ ์•ก์…˜์˜ ์ˆœ์„œ ์˜์กด์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

do(onNext:)์—์„œ updateImageList๋ฅผ ๋ณด๋‚ธ ํ›„ bugReportButtonDidTap์„ ๋ณด๋‚ด๋Š”๋ฐ, ๋‘ ์•ก์…˜์ด ์ˆœ์ฐจ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋œ๋‹ค๋Š” ๋ณด์žฅ์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Reactor์˜ mutate๊ฐ€ ๋™๊ธฐ์ ์ด๋ฏ€๋กœ ํ˜„์žฌ๋Š” ๋™์ž‘ํ•˜์ง€๋งŒ, ์ด๋ฏธ์ง€ ๋ฆฌ์ŠคํŠธ๋ฅผ Reactor State๋กœ ์ด๋™ํ•˜๋ฉด ์ด ์˜์กด์„ฑ์ด ๋ช…ํ™•ํ•ด์ง‘๋‹ˆ๋‹ค.

Projects/Presentation/Sources/InterestField/InterestFieldCheckReactor.swift (1)

40-48: ์ž๋™ ๋„ค๋น„๊ฒŒ์ด์…˜ ํƒ€์ด๋จธ ๊ตฌํ˜„์ด ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.

2์ดˆ ํƒ€์ด๋จธ ํ›„ steps.accept๋ฅผ ํ†ตํ•ด ๋„ค๋น„๊ฒŒ์ด์…˜์„ ํŠธ๋ฆฌ๊ฑฐํ•˜๋Š” ๊ตฌํ˜„์ด ReactorKit ํŒจํ„ด์„ ์ž˜ ๋”ฐ๋ฅด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. [weak self]๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋„ ๋ฐฉ์ง€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Projects/Presentation/Sources/DI/Assembly/SettingPresentationAssembly.swift (2)

48-56: NotificationSettingReactor DI ๋“ฑ๋ก์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

ViewModel์—์„œ Reactor๋กœ์˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์ด ์ ์ ˆํžˆ ๋ฐ˜์˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค.


109-130: InterestField ๊ด€๋ จ Reactor ๋“ฑ๋ก์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ตฌ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

InterestFieldReactor์™€ InterestFieldCheckReactor์˜ ์˜์กด์„ฑ ์ฃผ์ž…์ด ์ ์ ˆํžˆ ์„ค์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

Projects/Presentation/Sources/NotificationSetting/NotificationSettingViewController.swift (2)

90-125: bindAction ๊ตฌํ˜„์ด ReactorKit ํŒจํ„ด์„ ์ž˜ ๋”ฐ๋ฅด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ ์Šค์œ„์น˜ ๋ฒ„ํŠผ์— skip(1)์„ ์‚ฌ์šฉํ•˜์—ฌ ์ดˆ๊ธฐ๊ฐ’ ๋ฐฉ์ถœ์„ ๋ฐฉ์ง€ํ•˜๊ณ , ์ ์ ˆํ•œ ์•ก์…˜์œผ๋กœ ๋งคํ•‘ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


127-162: bindState ๊ตฌํ˜„์ด ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.

distinctUntilChanged()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ถˆํ•„์š”ํ•œ UI ์—…๋ฐ์ดํŠธ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ๊ฐ ์ƒํƒœ๋ฅผ ํ•ด๋‹น UI ์ปดํฌ๋„ŒํŠธ์— ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋ฐ”์ธ๋”ฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Projects/Presentation/Sources/InterestField/InterestFieldReactor.swift (1)

81-100: reduce ํ•จ์ˆ˜ ๊ตฌํ˜„์ด ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.

๊ฐ Mutation์— ๋Œ€ํ•œ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ช…ํ™•ํ•˜๊ณ , toggleSelectedInterest์˜ toggle ๋กœ์ง์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Projects/Presentation/Sources/NotificationSetting/NotificationSettingReactor.swift (2)

39-57: State ๊ตฌ์กฐ๊ฐ€ ์ž˜ ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

subscribeStates ๋”•์…”๋„ˆ๋ฆฌ์™€ computed properties๋ฅผ ์กฐํ•ฉํ•˜์—ฌ ๊ฐ ์•Œ๋ฆผ ํƒ€์ž…์˜ ์ƒํƒœ๋ฅผ ๊น”๋”ํ•˜๊ฒŒ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. isAllNotificationEnabled๊ฐ€ ๋ชจ๋“  ๊ฐœ๋ณ„ ์ƒํƒœ์˜ AND ์กฐ๊ฑด์œผ๋กœ ์ •์˜๋˜์–ด ์žˆ์–ด ๋…ผ๋ฆฌ์ ์œผ๋กœ ์˜ฌ๋ฐ”๋ฆ…๋‹ˆ๋‹ค.


89-108: reduce ํ•จ์ˆ˜ ๊ตฌํ˜„์ด ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.

๊ฐ Mutation์— ๋Œ€ํ•œ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ช…ํ™•ํ•˜๊ณ  ๋ถˆ๋ณ€์„ฑ์„ ์œ ์ง€ํ•˜๋ฉฐ ์ƒˆ๋กœ์šด State๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Copy link

@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 (3)
Projects/Presentation/Sources/BugReport/BugReportReactor.swift (2)

75-84: ์—๋Ÿฌ ์ฒ˜๋ฆฌ๊ฐ€ ๋ˆ„๋ฝ๋˜์–ด ์‚ฌ์šฉ์ž ํ”ผ๋“œ๋ฐฑ์ด ์—†์Šต๋‹ˆ๋‹ค.

๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜๋‚˜ ์„œ๋ฒ„ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ด๋„ ์‚ฌ์šฉ์ž์—๊ฒŒ ์•„๋ฌด๋Ÿฐ ํ”ผ๋“œ๋ฐฑ์ด ์ œ๊ณต๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‹คํŒจ ์‹œ ์—๋Ÿฌ ์ƒํƒœ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๋ณ„๋„์˜ mutation์„ ํ†ตํ•ด ์‚ฌ์šฉ์ž์—๊ฒŒ ์•Œ๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ”Ž ์—๋Ÿฌ ์ฒ˜๋ฆฌ ์ถ”๊ฐ€ ์ œ์•ˆ

State์— ์—๋Ÿฌ ํ”„๋กœํผํ‹ฐ ์ถ”๊ฐ€:

 public struct State {
     var title: String = ""
     var content: String = ""
     var imageList: [String] = []
     var majorType: String = "์ „์ฒด"
     var isBugReportButtonEnabled: Bool = false
     var isBugReportCompleted: Bool = false
+    var errorMessage: String?
 }

Mutation์— ์—๋Ÿฌ ์ผ€์ด์Šค ์ถ”๊ฐ€:

 public enum Mutation {
     case setTitle(String)
     case setContent(String)
     case setImageList([String])
     case setMajorType(String)
     case setBugReportButtonIsEnabled(Bool)
     case setBugReportCompleted
+    case setError(String)
 }

mutate์—์„œ ์—๋Ÿฌ ์ฒ˜๋ฆฌ:

 case .bugReportButtonDidTap:
     return reportBugUseCase.execute(req: .init(
         title: currentState.title,
         content: currentState.content,
         developmentArea: DevelopmentType(rawValue: currentState.majorType.uppercased()) ?? .all,
         attachmentUrls: currentState.imageList
     ))
     .asObservable()
     .map { _ in Mutation.setBugReportCompleted }
+    .catch { error in
+        return .just(.setError(error.localizedDescription))
+    }

ViewController์—์„œ ์—๋Ÿฌ ์ƒํƒœ ๊ตฌ๋…ํ•˜์—ฌ ํ† ์ŠคํŠธ ํ‘œ์‹œ:

reactor.state.compactMap { $0.errorMessage }
    .bind(onNext: { [weak self] message in
        self?.showJobisToast(text: message, inset: 70)
    })
    .disposed(by: disposeBag)

79-79: majorType์ด ํ•œ๊ธ€ ๋ฌธ์ž์—ด์ด๋ฏ€๋กœ DevelopmentType ๋ณ€ํ™˜์ด ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

majorType์˜ ๊ธฐ๋ณธ๊ฐ’์€ "์ „์ฒด"(ํ•œ๊ธ€)์ด๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์„ ํƒํ•˜๋Š” ๊ฐ’๋„ ํ•œ๊ธ€์ž…๋‹ˆ๋‹ค. DevelopmentType์˜ rawValue๋Š” "ALL", "SERVER", "WEB" ๋“ฑ ์˜๋ฌธ์ด๋ฏ€๋กœ, uppercased()๋ฅผ ์ ์šฉํ•ด๋„ ํ•œ๊ธ€์€ ๋ณ€ํ™˜๋˜์ง€ ์•Š์•„ DevelopmentType(rawValue:)์ด ํ•ญ์ƒ nil์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์„ ํƒํ•œ ๊ฐœ๋ฐœ ๋ถ„์•ผ๊ฐ€ ๋ฌด์‹œ๋˜๊ณ  ํ•ญ์ƒ .all๋กœ ์ „์†ก๋ฉ๋‹ˆ๋‹ค.

๐Ÿ”Ž ์ˆ˜์ • ๋ฐฉ์•ˆ

๋ฐฉ์•ˆ 1: ํ•œ๊ธ€-์˜๋ฌธ ๋งคํ•‘ ํ•จ์ˆ˜ ์ถ”๊ฐ€

private func mapMajorTypeToEnglish(_ majorType: String) -> String {
    switch majorType {
    case "์ „์ฒด": return "ALL"
    case "์„œ๋ฒ„": return "SERVER"
    case "์›น": return "WEB"
    case "์•ˆ๋“œ๋กœ์ด๋“œ": return "ANDROID"
    case "iOS": return "IOS"
    case "๋””์ž์ธ": return "DESIGN"
    case "ํฌ๋กœ์Šคํ”Œ๋žซํผ": return "CROSS_PLATFORM"
    default: return "ALL"
    }
}

// mutate์—์„œ ์‚ฌ์šฉ:
developmentArea: DevelopmentType(rawValue: mapMajorTypeToEnglish(currentState.majorType)) ?? .all

๋ฐฉ์•ˆ 2: State์—์„œ majorType์„ ์˜๋ฌธ์œผ๋กœ ์ €์žฅ

State๋ฅผ ์˜๋ฌธ์œผ๋กœ ์ €์žฅํ•˜๊ณ , UI ํ‘œ์‹œ์šฉ ํ•œ๊ธ€ ๋ณ€ํ™˜์€ ViewController์—์„œ ์ฒ˜๋ฆฌ:

 public struct State {
     var title: String = ""
     var content: String = ""
     var imageList: [String] = []
-    var majorType: String = "์ „์ฒด"
+    var majorType: String = "ALL"
     var isBugReportButtonEnabled: Bool = false
     var isBugReportCompleted: Bool = false
 }

๊ทธ๋ฆฌ๊ณ  ViewController์—์„œ ํ•œ๊ธ€๋กœ ๋ณ€ํ™˜:

reactor.state.map { $0.majorType }
    .distinctUntilChanged()
    .map { englishType in
        switch englishType {
        case "ALL": return "์ „์ฒด"
        case "SERVER": return "์„œ๋ฒ„"
        // ... ๋‚˜๋จธ์ง€ ๋งคํ•‘
        default: return "์ „์ฒด"
        }
    }
    .bind(to: bugReportMajorView.majorLabel.rx.text)
    .disposed(by: disposeBag)
Projects/Presentation/Sources/BugReport/BugReportViewController.swift (1)

207-214: ์™„๋ฃŒ ์ฒ˜๋ฆฌ ๋กœ์ง์— take(1)์ด ๋ˆ„๋ฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด์ „ ๋ฆฌ๋ทฐ์—์„œ ์ง€์ ๋œ reactor.action ๊ตฌ๋… ๋ฌธ์ œ๋Š” ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ API ํ˜ธ์ถœ ์™„๋ฃŒ ํ›„์— ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ํ˜„์žฌ ๊ตฌ๋…์— take(1) ์—ฐ์‚ฐ์ž๊ฐ€ ์—†์–ด, ์ด๋ก ์ ์œผ๋กœ isBugReportCompleted๊ฐ€ ์—ฌ๋Ÿฌ ๋ฒˆ true๋กœ ๋ณ€๊ฒฝ๋˜๋ฉด ํ† ์ŠคํŠธ์™€ pop์ด ์—ฌ๋Ÿฌ ๋ฒˆ ์‹คํ–‰๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ํ™”๋ฉด์ด dismiss๋œ ํ›„์—๋„ ๊ตฌ๋…์ด ์œ ์ง€๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ”Ž ์ œ์•ˆํ•˜๋Š” ์ˆ˜์ •
 reactor.state.map { $0.isBugReportCompleted }
     .distinctUntilChanged()
     .filter { $0 }
+    .take(1)
     .bind(onNext: { [weak self] _ in
         self?.showJobisToast(text: "๋ฒ„๊ทธ์ œ๋ณด๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.", inset: 70)
         self?.navigationController?.popViewController(animated: true)
     })
     .disposed(by: disposeBag)
๐Ÿ“œ Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

๐Ÿ“ฅ Commits

Reviewing files that changed from the base of the PR and between d509d60 and 2f664be.

๐Ÿ“’ Files selected for processing (2)
  • Projects/Presentation/Sources/BugReport/BugReportReactor.swift
  • Projects/Presentation/Sources/BugReport/BugReportViewController.swift
โฐ 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: JOBIS_DSM_iOS | JOBIS v2 CI | Build - iOS
๐Ÿ”‡ Additional comments (7)
Projects/Presentation/Sources/BugReport/BugReportViewController.swift (2)

10-10: ReactorKit ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

ํด๋ž˜์Šค ์‹œ๊ทธ๋‹ˆ์ฒ˜๊ฐ€ BaseReactorViewController<BugReportReactor>๋กœ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋ณ€๊ฒฝ๋˜์–ด ReactorKit ์•„ํ‚คํ…์ฒ˜์— ๋ถ€ํ•ฉํ•ฉ๋‹ˆ๋‹ค.


179-189: State ๋ฐ”์ธ๋”ฉ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋ฒ„ํŠผ ํ™œ์„ฑํ™” ์ƒํƒœ์™€ ์ „๊ณต ๋ ˆ์ด๋ธ”์ด reactor state์™€ ์ •ํ™•ํ•˜๊ฒŒ ๋ฐ”์ธ๋”ฉ๋˜์–ด ์žˆ์œผ๋ฉฐ, distinctUntilChanged()๋ฅผ ํ†ตํ•ด ๋ถˆํ•„์š”ํ•œ UI ์—…๋ฐ์ดํŠธ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Projects/Presentation/Sources/BugReport/BugReportReactor.swift (5)

8-18: ReactorKit ๊ตฌ์กฐ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

BaseReactor์™€ Stepper๋ฅผ ์ค€์ˆ˜ํ•˜๊ณ , ์˜์กด์„ฑ ์ฃผ์ž…์„ ํ†ตํ•ด use case๋ฅผ ๋ฐ›์•„ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๊ตฌ์กฐ๊ฐ€ ReactorKit ํŒจํ„ด์— ๋ถ€ํ•ฉํ•ฉ๋‹ˆ๋‹ค.


38-45: State ์ •์˜๊ฐ€ ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.

ํ•„์š”ํ•œ ์ƒํƒœ๋“ค์ด ๋ชจ๋‘ ์ •์˜๋˜์–ด ์žˆ์œผ๋ฉฐ, ReactorKit์˜ ๋‹จ๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ํ”Œ๋กœ์šฐ๋ฅผ ์ž˜ ๋”ฐ๋ฅด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. isBugReportCompleted ํ”Œ๋ž˜๊ทธ๋ฅผ ํ†ตํ•ด ์™„๋ฃŒ ์ƒํƒœ๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


51-63: ์ž…๋ ฅ ๊ฒ€์ฆ ๋กœ์ง์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ œ๋ชฉ๊ณผ ๋‚ด์šฉ์ด ๋ชจ๋‘ ์ž…๋ ฅ๋˜์—ˆ์„ ๋•Œ๋งŒ ๋ฒ„ํŠผ์„ ํ™œ์„ฑํ™”ํ•˜๋Š” ๋กœ์ง์ด ์ ์ ˆํ•˜๋ฉฐ, concat์„ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ mutation์„ ์ˆœ์ฐจ์ ์œผ๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐฉ์‹๋„ ReactorKit์˜ Best Practice๋ฅผ ๋”ฐ๋ฅด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


65-73: Navigation๊ณผ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋ถ„๋ฆฌ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

majorViewDidTap์—์„œ steps๋ฅผ ํ†ตํ•ด navigation์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์€ RxFlow ํŒจํ„ด์˜ ์˜ฌ๋ฐ”๋ฅธ ์‚ฌ์šฉ๋ฒ•์ด๋ฉฐ, ๋‚˜๋จธ์ง€ ์•ก์…˜๋“ค๋„ ์ ์ ˆํ•˜๊ฒŒ mutation์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


87-109: Reduce ๋กœ์ง์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  mutation์ด state์— ์ •ํ™•ํ•˜๊ฒŒ ๋ฐ˜์˜๋˜๊ณ  ์žˆ์œผ๋ฉฐ, ReactorKit์˜ ๋‹จ๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ํ”Œ๋กœ์šฐ๋ฅผ ์ž˜ ๋”ฐ๋ฅด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Copy link

@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: 0

โ™ป๏ธ Duplicate comments (1)
Projects/Presentation/Sources/BugReport/BugReportReactor.swift (1)

75-84: ์—๋Ÿฌ ์ฒ˜๋ฆฌ๊ฐ€ ์—ฌ์ „ํžˆ ๋ˆ„๋ฝ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

reportBugUseCase.execute()๊ฐ€ ์‹คํŒจํ•  ๊ฒฝ์šฐ ์‚ฌ์šฉ์ž์—๊ฒŒ ํ”ผ๋“œ๋ฐฑ์ด ์ œ๊ณต๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด์ „ ๋ฆฌ๋ทฐ์—์„œ ์ง€์ ๋œ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

๐Ÿ”Ž ์—๋Ÿฌ ์ฒ˜๋ฆฌ ์ถ”๊ฐ€ ์ œ์•ˆ
 case .bugReportButtonDidTap:
     return reportBugUseCase.execute(req: .init(
         title: currentState.title,
         content: currentState.content,
         developmentArea: DevelopmentType(localizedString: currentState.majorType) ?? .all,
         attachmentUrls: currentState.imageList
     ))
     .asObservable()
     .map { _ in Mutation.setBugReportCompleted }
+    .catch { error in
+        // TODO: ์—๋Ÿฌ๋ฅผ State์— ์ €์žฅํ•˜๊ฑฐ๋‚˜ ๋ณ„๋„ ์ฒ˜๋ฆฌ
+        print("Bug report failed: \(error)")
+        return .empty()
+    }
๐Ÿงน Nitpick comments (1)
Projects/Domain/Sources/Enums/DevelopmentType.swift (1)

29-38: ๋Œ€์†Œ๋ฌธ์ž ์ฒ˜๋ฆฌ ๋ฐ ์œ ์ง€๋ณด์ˆ˜์„ฑ ๊ฒ€ํ†  ํ•„์š”

์˜๋ฌธ ๋ฌธ์ž์—ด ๋งค์นญ์ด ๋Œ€์†Œ๋ฌธ์ž๋ฅผ ๊ตฌ๋ถ„ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด "all" ๋˜๋Š” "ALL"์„ ์ž…๋ ฅํ•˜๋ฉด nil์ด ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ์ž…๋ ฅ ์†Œ์Šค์— ๋”ฐ๋ผ ์ด๊ฒƒ์ด ์˜๋„๋œ ๋™์ž‘์ธ์ง€ ํ™•์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ, localizedString() ๋ฉ”์„œ๋“œ์™€ ์ด ์ด๋‹ˆ์…œ๋ผ์ด์ € ๊ฐ„์˜ ๋งคํ•‘์„ ๋™๊ธฐํ™”ํ•ด์•ผ ํ•˜๋ฏ€๋กœ, ํ–ฅํ›„ ์œ ์ง€๋ณด์ˆ˜ ์‹œ ๋ถˆ์ผ์น˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ”Ž ๋Œ€์†Œ๋ฌธ์ž ๋ฌด์‹œ ๋งค์นญ์„ ์œ„ํ•œ ๊ฐœ์„ ์•ˆ
 public init?(localizedString: String) {
-    switch localizedString {
+    switch localizedString.lowercased() {
-    case "์ „์ฒด", "All": self = .all
-    case "์„œ๋ฒ„", "Server": self = .server
-    case "์›น", "Web": self = .web
-    case "์•ˆ๋“œ๋กœ์ด๋“œ", "Android": self = .android
-    case "iOS": self = .ios
+    case "์ „์ฒด", "all": self = .all
+    case "์„œ๋ฒ„", "server": self = .server
+    case "์›น", "web": self = .web
+    case "์•ˆ๋“œ๋กœ์ด๋“œ", "android": self = .android
+    case "ios": self = .ios
     default: return nil
     }
 }
๐Ÿ“œ Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

๐Ÿ“ฅ Commits

Reviewing files that changed from the base of the PR and between 2f664be and 64036a1.

๐Ÿ“’ Files selected for processing (2)
  • Projects/Domain/Sources/Enums/DevelopmentType.swift
  • Projects/Presentation/Sources/BugReport/BugReportReactor.swift
๐Ÿงฐ Additional context used
๐Ÿงฌ Code graph analysis (1)
Projects/Presentation/Sources/BugReport/BugReportReactor.swift (3)
Projects/Modules/DesignSystem/Sources/Alert/AlertBuilder.swift (1)
  • setTitle (22-25)
Projects/Presentation/Sources/CompanyDetail/Components/CompanyDetailLabel.swift (1)
  • setContent (22-24)
Projects/Domain/Sources/Enums/DevelopmentType.swift (1)
  • localizedString (10-27)
โฐ 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). (2)
  • GitHub Check: JOBIS_DSM_iOS | JOBIS v2 CI | Test - iOS
  • GitHub Check: JOBIS_DSM_iOS | JOBIS v2 CI | Build - iOS
๐Ÿ”‡ Additional comments (8)
Projects/Presentation/Sources/BugReport/BugReportReactor.swift (8)

1-18: ํด๋ž˜์Šค ๊ตฌ์กฐ์™€ ์ดˆ๊ธฐํ™”๊ฐ€ ์˜ฌ๋ฐ”๋ฆ…๋‹ˆ๋‹ค.

ReactorKit ํŒจํ„ด์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋”ฐ๋ฅด๊ณ  ์žˆ์œผ๋ฉฐ, ์˜์กด์„ฑ ์ฃผ์ž… ๋ฐ RxFlow ํ†ตํ•ฉ์ด ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.


20-27: ์•ก์…˜ ์ •์˜๊ฐ€ ๋ช…ํ™•ํ•ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  ์‚ฌ์šฉ์ž ์ธํ„ฐ๋ž™์…˜์„ ์ ์ ˆํžˆ ํ‘œํ˜„ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


29-45: Mutation๊ณผ State ์ •์˜๊ฐ€ ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.

์ƒํƒœ ๋ณ€ํ™”๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ํ‘œํ˜„ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ์ดˆ๊ธฐ๊ฐ’์ด ํ•ฉ๋ฆฌ์ ์ž…๋‹ˆ๋‹ค.


51-63: ์ œ๋ชฉ๊ณผ ๋‚ด์šฉ ์—…๋ฐ์ดํŠธ ๋กœ์ง์ด ์˜ฌ๋ฐ”๋ฆ…๋‹ˆ๋‹ค.

๋ฒ„ํŠผ ํ™œ์„ฑํ™” ์กฐ๊ฑด์„ ์ •ํ™•ํžˆ ๊ฒ€์ฆํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


65-73: ์ด๋ฏธ์ง€ ๋ฆฌ์ŠคํŠธ, ๋ถ„์•ผ ํƒ€์ž… ์—…๋ฐ์ดํŠธ ๋ฐ ๋„ค๋น„๊ฒŒ์ด์…˜ ์ฒ˜๋ฆฌ๊ฐ€ ์˜ฌ๋ฐ”๋ฆ…๋‹ˆ๋‹ค.

Stepper ํŒจํ„ด์„ ์ ์ ˆํžˆ ํ™œ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


87-109: ๋ฆฌ๋“€์„œ ๊ตฌํ˜„์ด ์˜ฌ๋ฐ”๋ฆ…๋‹ˆ๋‹ค.

๊ฐ Mutation์„ ์ ์ ˆํžˆ State์— ๋ฐ˜์˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


75-84: ๋ฒ„๊ทธ ์ œ๋ณด ์„ฑ๊ณต ์‹œ์˜ ๋„ค๋น„๊ฒŒ์ด์…˜ ์ฒ˜๋ฆฌ์™€ ์•Œ๋ฆผ์€ ์ด๋ฏธ ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

BugReportViewController์˜ 207-212์ค„์—์„œ isBugReportCompleted ์ƒํƒœ๋ฅผ ๊ด€์ฐฐํ•˜์—ฌ "๋ฒ„๊ทธ์ œ๋ณด๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค." ํ† ์ŠคํŠธ ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•˜๊ณ  navigationController?.popViewController(animated: true)๋กœ ํ™”๋ฉด์„ ๋‹ซ๋Š” ๋กœ์ง์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

Likely an incorrect or invalid review comment.


75-84: DevelopmentType(localizedString:) ์ด๋‹ˆ์…œ๋ผ์ด์ €๋Š” ์ด๋ฏธ ์กด์žฌํ•˜๋ฏ€๋กœ ์ด ์ฝ”๋“œ๋Š” ์ •์ƒ์ž…๋‹ˆ๋‹ค.

Projects/Domain/Sources/Enums/DevelopmentType.swift (line 29-38)์—์„œ public init?(localizedString: String) ์ด๋‹ˆ์…œ๋ผ์ด์ €๊ฐ€ ์ •์˜๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ, line 79์˜ ์ฝ”๋“œ๋Š” ๋ฌธ์ œ์—†์ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

Likely an incorrect or invalid review comment.

@leejh08 leejh08 merged commit 8702a5d into develop Dec 25, 2025
2 of 5 checks passed
@leejh08 leejh08 deleted the feature/(#379)-Mypage_Detail_Refactoring branch December 25, 2025 23:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

โ™ป๏ธrefactor ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง ํ•  ๊ฒฝ์šฐ

Projects

None yet

Development

Successfully merging this pull request may close these issues.

๋งˆ์ดํŽ˜์ด์ง€ ๋‚ด๋ถ€ ๊ธฐ๋Šฅ ReactorKit Refactoring

2 participants