Skip to content

[Style] 프로필 사진 변경 기능 사용성 확보#205

Open
Remaked-Swain wants to merge 4 commits intodevelopfrom
style/#204-adjust-profile-image
Open

[Style] 프로필 사진 변경 기능 사용성 확보#205
Remaked-Swain wants to merge 4 commits intodevelopfrom
style/#204-adjust-profile-image

Conversation

@Remaked-Swain
Copy link
Copy Markdown
Member

@Remaked-Swain Remaked-Swain commented Apr 8, 2026

🌴 작업한 브랜치

✅ 작업한 내용

계정 설정 화면에서 보이는 프로필 사진 영역에 카메라 모양의 버튼을 제공합니다.
해당 버튼을 누르면 프로필 사진 변경이 가능하다는 시각적 UX를 제공하여 프로필 사진 변경 기능의 사용성을 용이하게 했습니다.

또 프로필 편집 후에 AppCoordinator 수준에서 새로운 유저 정보로 아예 덮어씌워버리니까 프로필 편집 화면의 이전 화면이 아닌, 아카이빙 탭이 나타나는 문제를 발견하여 조치했습니다.
이제 메인탭 상태를 초기화하지 않고 유지하는 것으로 기존에 열려있던 탭인 마이페이지 탭이 그대로 살아있게 합니다.

❗️PR Point

해당 이슈는 계정 설정 화면에서 프로필 사진 변경을 어떻게 하느냐라는 기능 사용성의 불편함에서 비롯되었습니다.
그러나 프로필 사진 변경을 위해 프로필 사진 영역을 두 번 탭해야 하는 새로운 불편함을 초래하기도 했습니다.
(계정 설정 화면에서 프사 터치 -> 프로필 편집 화면으로 이동 -> 프로필 편집 화면에서 프사 터치 -> 프로필 변경 기능)

기디 수준에서 재검토가 필요할 수 있습니다.
(사실 PM에게는 이미 알려줬음)

번외로, 프로필 정보 변경 관련해 메인탭 상태 변경 로직을 디버깅하는 과정에서 다음의 수정이 있었습니다.

  • 기존: 유저 로그인 세션 정보를 생성자를 통해 주입
  • 변경: @Shared 상태 공유

변경의 이유는 다음과 같습니다.

  1. 로그인 또는 비로그인 상태에서 User 값을 변경할 때, 변경사항을 상위 코디네이터급 리듀서로 전파하면서 직접 상태 관리해야함.
  2. 이러한 상태 변경 코드가 리듀서마다 작성되어야 하며 네비게이션 스택에 따라 각 피처급 리듀서를 순회하면서 다시 상태 변경을 챙겨줘야함.
  3. 유저 로그인 세션이라는 단일진실공급원을 AppCoordinator가 관리하면서 하위 화면에는 생성자 주입을 하는, 로그인 상태가 변경되었을 때 자동으로 갱신되는 방식이 더 자연스럽다고 판단해 기존안으로 구현하였으나, 현재에 이르러서는 상태 관리 로직이 더 많아짐에 따라 매우 귀찮고 알아보기 힘들어짐.

아래의 사항을 주로 고민했습니다.

  1. 마이페이지 탭 및 그 하위 화면은 로그인 필수 기능으로써, 유저 정보가 옵셔널로 선언되면 그 의미가 변질됨.
  2. 하지만 UserSessionStatus는 열거형이므로, 로그인된 상태에서만 접근할 수 있는 화면임에도 불구하고 비로그인 상태까지 고려하여 옵셔널로 선언해야함.
  3. 따라서 getter/setter를 활용한 프록시 패턴을 적용해 뷰에서 유저 정보를 읽거나 자식 리듀서 내에서 유저 정보를 쓸 때 store.user?.nickname처럼 코드를 작성하지 않도록 만듦.
  4. 유저 값 변경에 대한 모든 Delegate 액션을 제거하여 코드 다이어트.

📸 스크린샷

작은 변경사항이라 생략합니다.

📟 관련 이슈

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능
    • 내 페이지의 프로필 이미지 우측 하단에 카메라 아이콘 버튼이 추가되었습니다. 사용자가 해당 버튼을 탭하면 프로필 편집 화면이 바로 실행됩니다. 기존의 프로필 이미지 탭 및 닉네임 편집 동작은 그대로 유지됩니다.

@Remaked-Swain Remaked-Swain added this to the 3차 스프린트 milestone Apr 8, 2026
@Remaked-Swain Remaked-Swain requested a review from OneTen19 April 8, 2026 11:45
@Remaked-Swain Remaked-Swain self-assigned this Apr 8, 2026
@Remaked-Swain Remaked-Swain added Style 🖼️ UI 작업 금용 🐲 금용 작업 labels Apr 8, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 8, 2026

Walkthrough

프로필 이미지에 편집 버튼을 오버레이하고, 사용자 세션 상태를 AppStorage 기반의 공유 상태(userSessionStatus)로 전환해 여러 코디네이터·피처들이 해당 공유 상태를 통해 사용자 정보를 읽고 갱신하도록 변경. 일부 delegate 전달(프로필 업데이트 관련)이 제거되어 이벤트 전파 방식이 바뀜.

Changes

Cohort / File(s) Summary
계정 설정 UI
Neki-iOS/Features/MyPage/Sources/Presentation/Sources/View/AccountPreferenceView.swift
프로필 KFImageZStack으로 래핑해 하단-우측에 카메라 아이콘 Button 오버레이 추가. 탭 시 .editProfileButtonTapped 디스패치. 기존 닉네임/편집 제스처와 레이아웃 유지.
앱 코디네이션 / 라우팅
Neki-iOS/APP/Sources/Application/AppCoordinator.swift, Neki-iOS/APP/Sources/MainTab/MainTabCoordinator.swift, Neki-iOS/Features/MyPage/Sources/Presentation/Sources/Coordinator/MyPageCoordinator.swift
사용자 정보를 직접 전달하던 패턴을 제거하고 userSessionStatus 기반 공유 상태로 전환. .userSessionStatusChanged(.signedIn) 및 라우트 전환 로직 수정, Delegate.profileUpdated 케이스 및 프로필 업데이트 전달 분기 제거. MyPage 및 MainTab 초기화에서 더 이상 User 인자를 요구하지 않도록 변경.
도메인 - 사용자 더미
Neki-iOS/Core/Sources/Auth/Sources/Domain/Sources/Entities/User.swift
테스트/플레이스홀더용 static var dummy: User 추가.
MyPage 피처 상태 변경
Neki-iOS/Features/MyPage/Sources/Presentation/Sources/Feature/MyPageFeature.swift
user 저장 속성 → @Shared userSessionStatususer 계산 프로퍼티로 변경. 초기화에서 user 직접 요구 제거.
계정 설정 피처 상태 변경
Neki-iOS/Features/MyPage/Sources/Presentation/Sources/Feature/AccountPreferenceFeature.swift
user 저장 속성 제거, @Shared userSessionStatus 추가 및 user 계산 프로퍼티 도입. 언어/식별자 일관성(유저ID 캡처명) 및 UserDefaults 키 포맷 일부 수정(언어표기 변경).
프로필 편집 피처 변경
Neki-iOS/Features/MyPage/Sources/Presentation/Sources/Feature/ProfileEditFeature.swift
저장된 user 제거하고 @Shared userSessionStatus 도입. user 계산 프로퍼티로 getter/setter 구현해 업데이트 시 userSessionStatus 갱신. profileUpdated delegate 액션 및 관련 포워딩 제거; 업데이트 성공 시 상태 직접 갱신 및 뷰 닫음.

Sequence Diagram(s)

sequenceDiagram
    participant AppCoord as AppCoordinator
    participant Storage as AppStorage\n(UserSessionStatus)
    participant MainTab as MainTabCoordinator
    participant MyPage as MyPageCoordinator
    participant ProfileEdit as ProfileEditFeature

    AppCoord->>Storage: userSessionStatus = .signedIn(user)
    AppCoord->>MainTab: route = .mainTab() (init)
    MainTab->>MyPage: init root (reads user from Storage)
    MyPage->>MyPage: user = Storage.signedIn? -> computed user

    MyPage->>AccountPref: profileTapped -> push accountPreference
    AccountPref->>ProfileEdit: editProfileButtonTapped -> push profileEdit
    ProfileEdit->>Storage: update userSessionStatus = .signedIn(updatedUser)
    Storage-->>MyPage: (shared) computed user now reflects updatedUser
    MyPage-->>UI: UI reflects updatedUser
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning 계정설정화면의 카메라 버튼 추가라는 주요 변경 외에도, 사용자 세션 상태 관리를 AppStorage 기반 공유 상태로 광범위하게 리팩터링한 변경사항이 포함되어 있습니다. 유저 세션 주입 방식 변경(AppCoordinator, MainTabCoordinator, MyPageCoordinator 등의 리팩터링)은 이슈 #204의 범위를 넘어서는 아키텍처 변경으로 보이며, 별도의 리팩터링 PR로 분리하는 것을 검토하십시오.
Linked Issues check ❓ Inconclusive PR의 코드 변경사항들이 #204의 요구사항인 계정설정화면에서 프로필 변경 경로 추가를 구현하고 있으나, 그 과정에서 예기치 않은 리팩터링이 포함되었습니다. 계정설정화면에 카메라 버튼 추가로 주요 목표는 달성했으나, 유저 세션 주입 방식의 광범위한 리팩터링이 함께 진행되어 변경 범위가 이슈 범위를 초과했는지 명확히 해야 합니다.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed 제목은 프로필 사진 변경 기능 사용성 개선이라는 주요 변경사항을 명확히 반영하고 있습니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed PR 설명이 필수 섹션을 모두 포함하며 상세하게 작성되었으나, 스크린샷 섹션이 명시적으로 생략되었습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch style/#204-adjust-profile-image

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.

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@Neki-iOS/Features/MyPage/Sources/Presentation/Sources/View/AccountPreferenceView.swift`:
- Around line 80-82: The camera/image Button currently sends
store.send(.editProfileButtonTapped) which routes via MyPageCoordinator to
.profileEdit(...) and thus opens the full profile edit screen (same as the
nickname pencil), so change the flow by adding a distinct action (e.g.
editProfileImageButtonTapped) to the action enum and reducer, update the Button
to send that new action, and add a new coordinator route/handling for the
image-only flow (e.g. profileImageEdit or a direct image picker entry) in
MyPageCoordinator where you previously route .profileEdit(.init(user:
state.root.user)); also add an accessibility label to the image button (e.g.
.accessibilityLabel("프로필 사진 변경")) to improve VoiceOver support.
- Around line 80-84: The camera Image button (Button sending
store.send(.editProfileButtonTapped) with Image(.iconProfileCamera)) lacks
accessible labeling and a minimum tappable area; update the Button to provide an
accessibilityLabel (e.g., "Edit profile photo"), an accessibilityHint (e.g.,
"Opens camera to change your profile picture"), ensure it has
.accessibilityAddTraits(.isButton), and enlarge its tap target by applying a
minimum frame (frame(minWidth: 44, minHeight: 44)) or additional padding plus
contentShape(Rectangle()) so the hit area meets 44pt minimum while keeping the
existing action and image.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 83a2af7c-4027-4be6-965e-3f186e4606b2

📥 Commits

Reviewing files that changed from the base of the PR and between 1e2c72b and 2a66aa8.

📒 Files selected for processing (1)
  • Neki-iOS/Features/MyPage/Sources/Presentation/Sources/View/AccountPreferenceView.swift

Comment on lines +80 to +82
Button {
store.send(.editProfileButtonTapped)
} label: {
Copy link
Copy Markdown

@coderabbitai coderabbitai bot Apr 8, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether editProfileButtonTapped routes directly to image picking
# or just navigates to profile edit screen.

fd -i 'AccountPreferenceFeature.swift' --exec sed -n '1,260p' {}
rg -n -C4 '\beditProfileButtonTapped\b' --type swift
rg -n -C4 '\b(profile|camera|image|picker|photo)\b' --type swift

Repository: YAPP-Github/Neki-iOS

Length of output: 50376


카메라 버튼이 프로필 편집 화면을 거쳐 기대되는 직접 사진 변경 플로우를 구현하지 못합니다.

Line 81의 .editProfileButtonTapped 액션은 MyPageCoordinator.swift:49–50에서 .profileEdit(.init(user: state.root.user))로 라우팅되어, 결과적으로 프로필 편집 화면으로 네비게이션됩니다. 이는 Line 93의 닉네임 편집(연필 아이콘)과 동일한 플로우입니다. 따라서 카메라 버튼은 "바로 사진 변경" 기능이 아니라 기존 편집 화면을 거치게 됩니다. 카메라 선택을 위해 별도의 액션(editProfileImageButtonTapped 등) 및 라우팅 경로를 추가하여 구현하시기 바랍니다.

추가로 Line 83의 이미지 버튼은 명시적 접근성 레이블 없이 아이콘만 표시되어, VoiceOver 사용자 경험이 저하될 수 있습니다. .accessibilityLabel("프로필 사진 변경") 등의 수정자를 추가하세요.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@Neki-iOS/Features/MyPage/Sources/Presentation/Sources/View/AccountPreferenceView.swift`
around lines 80 - 82, The camera/image Button currently sends
store.send(.editProfileButtonTapped) which routes via MyPageCoordinator to
.profileEdit(...) and thus opens the full profile edit screen (same as the
nickname pencil), so change the flow by adding a distinct action (e.g.
editProfileImageButtonTapped) to the action enum and reducer, update the Button
to send that new action, and add a new coordinator route/handling for the
image-only flow (e.g. profileImageEdit or a direct image picker entry) in
MyPageCoordinator where you previously route .profileEdit(.init(user:
state.root.user)); also add an accessibility label to the image button (e.g.
.accessibilityLabel("프로필 사진 변경")) to improve VoiceOver support.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

의도한 사항이므로 기각.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@Remaked-Swain, 이해했습니다. PR 설명에서도 해당 이중 탭 흐름(계정 설정 화면 → 프로필 편집 화면 → 프로필 변경)이 의도적으로 허용된 동작임을 명시하셨군요. 감사합니다!

(╯°□°)╯

Comment on lines +80 to +84
Button {
store.send(.editProfileButtonTapped)
} label: {
Image(.iconProfileCamera)
}
Copy link
Copy Markdown

@coderabbitai coderabbitai bot Apr 8, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify accessibility metadata presence for the new camera button area.
rg -n -C3 'iconProfileCamera|accessibilityLabel|accessibilityHint|minWidth:\s*44|minHeight:\s*44' --type swift

Repository: YAPP-Github/Neki-iOS

Length of output: 1728


🏁 Script executed:

# Read the full context around the button in AccountPreferenceView.swift
cat -n Neki-iOS/Features/MyPage/Sources/Presentation/Sources/View/AccountPreferenceView.swift | sed -n '70,95p'

Repository: YAPP-Github/Neki-iOS

Length of output: 1163


카메라 버튼의 접근성(VoiceOver 라벨/탭 영역) 개선이 필요합니다.

이미지 단독 버튼은 의미 전달이 약하고 탭 타깃이 작을 수 있습니다. 최소 탭 영역(44pt)과 접근성 라벨/힌트를 추가해주세요.

개선 예시
                Button {
                    store.send(.editProfileButtonTapped)
                } label: {
                    Image(.iconProfileCamera)
+                        .padding(10)
+                        .background(.white)
+                        .clipShape(Circle())
                }
+                .frame(minWidth: 44, minHeight: 44)
+                .contentShape(Rectangle())
+                .accessibilityLabel("프로필 사진 변경")
+                .accessibilityHint("프로필 사진을 변경하는 화면으로 이동")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@Neki-iOS/Features/MyPage/Sources/Presentation/Sources/View/AccountPreferenceView.swift`
around lines 80 - 84, The camera Image button (Button sending
store.send(.editProfileButtonTapped) with Image(.iconProfileCamera)) lacks
accessible labeling and a minimum tappable area; update the Button to provide an
accessibilityLabel (e.g., "Edit profile photo"), an accessibilityHint (e.g.,
"Opens camera to change your profile picture"), ensure it has
.accessibilityAddTraits(.isButton), and enlarge its tap target by applying a
minimum frame (frame(minWidth: 44, minHeight: 44)) or additional padding plus
contentShape(Rectangle()) so the hit area meets 44pt minimum while keeping the
existing action and image.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

당장은 접근성 관련 리팩토링을 진행할 예정이 없으므로 기각.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@Remaked-Swain, 알겠습니다. 나중에 접근성 개선을 진행하실 때 참고할 수 있도록 이슈로 남겨드릴까요?

(´・ω・`)

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.

Caution

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

⚠️ Outside diff range comments (1)
Neki-iOS/APP/Sources/Application/AppCoordinator.swift (1)

200-211: ⚠️ Potential issue | 🟡 Minor

잠재적 로직 오류: .signedOut 케이스에서 불필요한 guard 문

Line 202의 guard case .expired = newStatus else { return .none }.signedOut 케이스 내부에 있으므로 newStatus.signedOut일 때 항상 early return 됩니다. 이로 인해 토스트 메시지가 절대 표시되지 않습니다.

의도된 동작이라면 불필요한 코드이고, 버그라면 토스트가 표시되지 않는 문제가 있습니다.

🔧 의도에 따른 수정 제안

토스트가 .signedOut에서 필요 없는 경우:

 case .signedOut:
     state.route = .auth(.init())
-    guard case .expired = newStatus else { return .none }
-    state.toastItem = .init("다시 로그인 해주세요.")
     return .none
     
 case .expired:
     state.route = .auth(.init())
-    guard case .expired = newStatus else { return .none }
     state.toastItem = .init("다시 로그인 해주세요.")
     return .none
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Neki-iOS/APP/Sources/Application/AppCoordinator.swift` around lines 200 -
211, The .signedOut case contains an erroneous guard "guard case .expired =
newStatus else { return .none }" which will always fail when handling .signedOut
and prevents the toast from ever being set; remove that guard from the
.signedOut branch so state.route = .auth(.init()) is followed by state.toastItem
= .init("다시 로그인 해주세요.") and return .none, or alternatively, if the toast should
only appear when newStatus == .expired move the expiration check out of the
.signedOut branch and perform "guard case .expired = newStatus" before setting
the toast; update the code referencing state.route, newStatus, and
state.toastItem accordingly.
🧹 Nitpick comments (2)
Neki-iOS/Features/MyPage/Sources/Presentation/Sources/Feature/AccountPreferenceFeature.swift (1)

75-86: userID 캡처 시 잠재적 엣지 케이스

Line 79에서 state.user.id를 캡처할 때, 이론적으로 userSessionStatus.signedIn이 아닌 경우 User.dummyid: -1이 캡처될 수 있습니다. 이 경우 "TermsAgreed_-1" 키가 삭제되어 실제 사용자의 동의 정보가 남게 됩니다.

현재 흐름에서는 로그인된 상태에서만 회원탈퇴 버튼이 노출되므로 실제 문제가 발생할 가능성은 낮지만, 방어적 코딩을 권장합니다.

🛡️ 방어적 코딩 제안
 case .unregisterButtonTapped:
     state.isUnregisterAlertPresented = false
+    guard case let .signedIn(user) = state.userSessionStatus else { return .none }
     state.isLoading = true
     
-    return .run { [userID = state.user.id] send in
+    return .run { [userID = user.id] send in
         try await authClient.withdraw()
         UserDefaults.standard.removeObject(forKey: "TermsAgreed_\(userID)")
         await send(.didWithdraw)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@Neki-iOS/Features/MyPage/Sources/Presentation/Sources/Feature/AccountPreferenceFeature.swift`
around lines 75 - 86, The current .unregisterButtonTapped run task captures
state.user.id which may be User.dummy (-1) in edge cases; change the capture and
deletion to be defensive: capture a validated userID (from state.user.id or from
authClient/session) before calling authClient.withdraw, and only call
UserDefaults.standard.removeObject(forKey: "TermsAgreed_\(userID)") if that
userID is a valid signed-in id (e.g., not -1 or nil); update the
.unregisterButtonTapped handler to validate the userID before removing the key
and to avoid deleting "TermsAgreed_-1".
Neki-iOS/APP/Sources/Application/AppCoordinator.swift (1)

194-198: 사용되지 않는 user 변수 - 컴파일러 경고 발생 가능

case let .signedIn(user)에서 추출된 user 변수가 사용되지 않아 컴파일러 경고가 발생할 수 있습니다.

🔧 제안된 수정
-                case let .signedIn(user):
+                case .signedIn:
                     if case .mainTab = state.route { return .none }
                     state.route = .mainTab(.init())
                     return .none
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Neki-iOS/APP/Sources/Application/AppCoordinator.swift` around lines 194 -
198, The pattern match binds an unused user in the switch (case let
.signedIn(user)) causing a compiler warning; change the pattern to not bind the
value (use case .signedIn or case let .signedIn(_) ) in the switch on newStatus
to eliminate the unused-variable warning while keeping the existing logic that
sets state.route = .mainTab(.init()) and early-returns when state.route is
already .mainTab.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@Neki-iOS/APP/Sources/Application/AppCoordinator.swift`:
- Around line 200-211: The .signedOut case contains an erroneous guard "guard
case .expired = newStatus else { return .none }" which will always fail when
handling .signedOut and prevents the toast from ever being set; remove that
guard from the .signedOut branch so state.route = .auth(.init()) is followed by
state.toastItem = .init("다시 로그인 해주세요.") and return .none, or alternatively, if
the toast should only appear when newStatus == .expired move the expiration
check out of the .signedOut branch and perform "guard case .expired = newStatus"
before setting the toast; update the code referencing state.route, newStatus,
and state.toastItem accordingly.

---

Nitpick comments:
In `@Neki-iOS/APP/Sources/Application/AppCoordinator.swift`:
- Around line 194-198: The pattern match binds an unused user in the switch
(case let .signedIn(user)) causing a compiler warning; change the pattern to not
bind the value (use case .signedIn or case let .signedIn(_) ) in the switch on
newStatus to eliminate the unused-variable warning while keeping the existing
logic that sets state.route = .mainTab(.init()) and early-returns when
state.route is already .mainTab.

In
`@Neki-iOS/Features/MyPage/Sources/Presentation/Sources/Feature/AccountPreferenceFeature.swift`:
- Around line 75-86: The current .unregisterButtonTapped run task captures
state.user.id which may be User.dummy (-1) in edge cases; change the capture and
deletion to be defensive: capture a validated userID (from state.user.id or from
authClient/session) before calling authClient.withdraw, and only call
UserDefaults.standard.removeObject(forKey: "TermsAgreed_\(userID)") if that
userID is a valid signed-in id (e.g., not -1 or nil); update the
.unregisterButtonTapped handler to validate the userID before removing the key
and to avoid deleting "TermsAgreed_-1".

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: d1d1c30d-145a-46d4-a19c-aa21e63c1f32

📥 Commits

Reviewing files that changed from the base of the PR and between 5286ff7 and c75da04.

📒 Files selected for processing (7)
  • Neki-iOS/APP/Sources/Application/AppCoordinator.swift
  • Neki-iOS/APP/Sources/MainTab/MainTabCoordinator.swift
  • Neki-iOS/Core/Sources/Auth/Sources/Domain/Sources/Entities/User.swift
  • Neki-iOS/Features/MyPage/Sources/Presentation/Sources/Coordinator/MyPageCoordinator.swift
  • Neki-iOS/Features/MyPage/Sources/Presentation/Sources/Feature/AccountPreferenceFeature.swift
  • Neki-iOS/Features/MyPage/Sources/Presentation/Sources/Feature/MyPageFeature.swift
  • Neki-iOS/Features/MyPage/Sources/Presentation/Sources/Feature/ProfileEditFeature.swift

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Style 🖼️ UI 작업 금용 🐲 금용 작업

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Style] 프로필 변경 UI/UX 변경

1 participant