-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WEAV-135] 프로필, 이상형 정보 입력 Intro 뷰 생성 #45
Conversation
Walkthrough이 풀 리퀘스트는 주로 Changes
Possibly related PRs
Suggested labels
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 8
🧹 Outside diff range and nitpick comments (28)
Projects/Features/SignUp/Sources/ProfileInput/ProfileIntro/ProfileIntroIntent.swift (3)
36-44
: 프로토콜 문서화 개선 필요각 메서드의 목적과 사용법을 명확히 하기 위해 문서화가 필요합니다.
다음과 같이 문서화를 추가하는 것을 제안합니다:
protocol Intentable { - // content + /// 다음 화면으로 전환하는 메서드 func pushNextView() async + + /// 다음 버튼 탭 이벤트 처리 메서드 func onTapNextButton() - // default + /// 뷰가 나타날 때 호출되는 메서드 func onAppear() + + /// 비동기 작업을 처리하는 메서드 func task() async }
60-65
: 미구현된 메서드들의 용도 명시 필요
onAppear()
,task()
,onTapNextButton()
가 비어있는 이유와 향후 구현 계획을 주석으로 명시해주세요.특히
onTapNextButton()
은 수동 네비게이션을 위해 필요할 수 있으므로, 구현 여부를 검토해주세요.- func onAppear() {} + /// 현재는 필요한 초기화 작업이 없음 + func onAppear() {} - func task() async {} + /// 현재는 필요한 비동기 작업이 없음 + func task() async {} // content - func onTapNextButton() {} + /// 자동 전환 외에 수동 전환이 필요한 경우를 위한 메서드 + func onTapNextButton() { + Task { + await pushNextView() + } + }
14-14
: MARK 주석 형식 수정 필요SwiftLint 규칙에 따라 MARK 주석 형식을 수정해주세요.
다음과 같이 수정을 제안합니다:
-//MARK: - Intent +// MARK: - Intent -//MARK: - Intentable +// MARK: - Intentable -//MARK: - Intentable +// MARK: - IntentableAlso applies to: 34-34, 51-51
🧰 Tools
🪛 SwiftLint
[Warning] 14-14: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 14-14: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
Projects/Features/SignUp/Sources/DreamPartnerInput/DreamPartnerIntro/DreamPartnerIntroIntent.swift (2)
34-49
: 프로토콜 정의 위치 및 구조 개선 필요이전 PR의 학습 내용을 참고하여, 프로토콜 정의를 클래스 extension 내부에 두는 것은 의도적인 설계로 보입니다. 하지만 다음 개선사항을 고려해주세요:
- 프로토콜 메서드들의 목적에 따른 그룹화가 필요합니다.
- "content"와 "default" 주석 대신 명확한 문서화 주석이 필요합니다.
다음과 같은 구조를 제안드립니다:
protocol Intentable { + /// Navigation related methods func pushNextView() async func onTapNextButton() + /// Lifecycle related methods func onAppear() func task() async }🧰 Tools
🪛 SwiftLint
[Warning] 34-34: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 34-34: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
14-14
: MARK 주석 포맷 수정 필요SwiftLint 경고에 따라 MARK 주석 포맷을 수정해주세요.
다음과 같이 수정이 필요합니다:
- //MARK: - Intent + // MARK: - Intent - //MARK: - Intentable + // MARK: - IntentableAlso applies to: 34-34, 51-51
🧰 Tools
🪛 SwiftLint
[Warning] 14-14: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 14-14: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
Projects/Features/SignUp/Sources/ProfileInput/AuthName/AuthNameInputIntent.swift (2)
Line range hint
64-69
: 입력 유효성 검사 및 디버그 코드 개선 필요
- 다음 화면으로 이동하기 전에 이름 입력값의 유효성 검사가 필요합니다.
- 프로덕션 코드에
다음과 같이 개선을 제안합니다:
func onTapNextButton(state: AuthNameInputModel.Stateful) { Task { var payload = input.input + guard !state.inputText.isEmpty else { return } payload.name = state.inputText - print(state.inputText) await pushNextView(payload: payload) } }
네비게이션 흐름 변경이 불완전하게 적용되었습니다
코드베이스 분석 결과,
.dreamPartnerAgeRange
와.dreamPartnerIntro
경로가 동시에 존재하며 일관성이 없습니다:
DreamPartnerIntroIntent.swift
에서는 여전히.dreamPartnerAgeRange
로 네비게이션하고 있습니다PathTypes.swift
에 두 경로가 모두 정의되어 있어 혼선의 여지가 있습니다NavigationStack.swift
에도 두 경로가 모두 구현되어 있습니다🔗 Analysis chain
Line range hint
70-74
: 네비게이션 흐름 변경 검증 필요네비게이션 흐름이
.dreamPartnerAgeRange
에서.dreamPartnerIntro
로 변경되었습니다. 이는 의도된 변경으로 보이지만, 전체 회원가입 플로우에 미치는 영향을 확인해야 합니다.다음 스크립트를 실행하여 관련된 네비게이션 변경사항을 확인하세요:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify navigation flow changes across the codebase # Check for any remaining references to the old navigation path rg "dreamPartnerAgeRange" # Check for consistent usage of the new navigation path rg "dreamPartnerIntro"Length of output: 1352
Projects/Features/SignUp/Sources/ProfileInput/ProfileIntro/ProfileIntroModel.swift (4)
13-40
: 문서화 개선이 필요합니다.각 프로토콜과 프로퍼티에 대한 문서화 주석을 추가하면 코드의 가독성과 유지보수성이 향상될 것 같습니다.
다음과 같이 문서화 주석을 추가해보세요:
+/// 프로필 소개 화면의 상태를 관리하는 모델 final class ProfileIntroModel: ObservableObject { //MARK: Stateful + /// 프로필 소개 화면의 상태를 정의하는 프로토콜 protocol Stateful { + /// 입력값의 유효성 검증 상태 var isValidated: Bool { get } + /// 로딩 상태 var isLoading: Bool { get } + /// 에러 뷰 표시 상태 var showErrorView: ErrorModel? { get } + /// 에러 알림 표시 상태 var showErrorAlert: ErrorModel? { get } }🧰 Tools
🪛 SwiftLint
[Warning] 15-15: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 28-28: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 15-15: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 28-28: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
58-60
: 유효성 검증 로직 강화가 필요합니다.
setValidation
메서드에 입력값 검증 로직이 없습니다. 잘못된 상태 변경을 방지하기 위해 검증 로직을 추가하는 것이 좋을 것 같습니다.다음과 같이 개선해보세요:
func setValidation(value: Bool) { + // 현재 상태와 동일한 경우 불필요한 상태 업데이트 방지 + guard isValidated != value else { return } isValidated = value }
15-15
: 코드 스타일 개선이 필요합니다.SwiftLint 분석 결과에 따라 MARK 주석 형식을 수정해야 합니다.
다음과 같이 수정해주세요:
- //MARK: Stateful + // MARK: - Stateful - //MARK: State Properties + // MARK: - State Properties -//MARK: - Actionable +// MARK: - ActionableAlso applies to: 28-28, 42-42
🧰 Tools
🪛 SwiftLint
[Warning] 15-15: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 15-15: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
1-12
: 아키텍처 문서화가 필요합니다.이 파일이 MVI 아키텍처 패턴을 따르고 있다는 것을 명시하는 파일 수준의 문서화가 있으면 좋을 것 같습니다.
파일 상단에 다음과 같은 문서화를 추가해보세요:
+/// ProfileIntroModel은 MVI 아키텍처의 Model 컴포넌트를 구현합니다. +/// - State 관리: `Stateful` 프로토콜을 통해 뷰의 상태를 관리합니다. +/// - Action 처리: `ProfileIntroModelActionable` 프로토콜을 통해 상태 변경 액션을 처리합니다. +/// - Intent 연동: ProfileIntroIntent와 함께 작동하여 사용자 인터랙션을 처리합니다.Projects/Features/SignUp/Sources/DreamPartnerInput/DreamPartnerIntro/DreamPartnerIntroModel.swift (3)
13-40
: 프로토콜과 상태 관리가 잘 구현되어 있습니다.상태 관리를 위한 구조가 명확하게 설계되어 있으며, SwiftUI의
ObservableObject
를 적절히 활용하고 있습니다. 다만, 문서화를 추가하면 더 좋을 것 같습니다.각 프로퍼티와 프로토콜에 대한 문서화를 추가하는 것을 제안드립니다:
+ /// 이상형 소개 화면의 상태를 관리하는 프로토콜 protocol Stateful { + /// 유효성 검증 상태 var isValidated: Bool { get } + /// 로딩 상태 var isLoading: Bool { get } + /// 에러 표시 상태 var showErrorView: ErrorModel? { get } var showErrorAlert: ErrorModel? { get } }🧰 Tools
🪛 SwiftLint
[Warning] 15-15: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 28-28: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 15-15: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 28-28: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
42-78
: 에러 처리 로직 개선이 필요합니다.현재 구현은 깔끔하지만, 에러 처리를 좀 더 견고하게 만들 수 있습니다.
다음과 같은 개선사항을 제안드립니다:
func showErrorView(error: ErrorModel) { + guard !isLoading else { return } showErrorView = error } func showErrorAlert(error: ErrorModel) { + guard !isLoading else { return } showErrorAlert = error } func resetError() { + guard showErrorView != nil || showErrorAlert != nil else { return } showErrorView = nil showErrorAlert = nil }🧰 Tools
🪛 SwiftLint
[Warning] 42-42: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 42-42: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
15-15
: MARK 주석 형식을 수정해주세요.SwiftLint 분석 결과에 따라 MARK 주석 형식을 수정해야 합니다.
다음과 같이 수정해주세요:
- //MARK: Stateful + // MARK: - Stateful - //MARK: State Properties + // MARK: - State Properties -//MARK: - Actionable +// MARK: - ActionableAlso applies to: 28-28, 42-42
🧰 Tools
🪛 SwiftLint
[Warning] 15-15: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 15-15: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
Projects/Features/SignUp/Sources/DreamPartnerInput/DreamPartnerIntro/DreamPartnerJobModel.swift (3)
14-29
: 프로토콜 문서화 개선 및 MARK 포맷 수정 필요프로토콜의 각 프로퍼티에 대한 문서화 주석을 추가하면 좋을 것 같습니다. 또한 MARK 주석 포맷을 수정해야 합니다.
다음과 같이 수정해주세요:
- //MARK: Stateful + // MARK: - Stateful그리고 각 프로퍼티에 대한 문서화를 추가해주세요:
/// 선택된 직업 배열 var selectedJobArray: [JobOccupation] { get } /// 선택이 유효한지 여부 var isValidated: Bool { get }🧰 Tools
🪛 SwiftLint
[Warning] 16-16: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 16-16: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
32-35
: isValidated 프로퍼티 가독성 개선 제안
isValidated
프로퍼티의 의도를 더 명확하게 표현할 수 있습니다.다음과 같이 수정하는 것을 제안합니다:
- var isValidated: Bool { - selectedJobArray.isNotEmpty - } + var isValidated: Bool { + return !selectedJobArray.isEmpty + }
48-59
: Actionable 프로토콜 문서화 필요각 메서드의 용도와 매개변수에 대한 설명을 추가하면 좋을 것 같습니다.
다음과 같이 문서화를 추가해주세요:
/// 선택된 직업 배열을 설정합니다 /// - Parameter jobs: 설정할 직업 배열 func setSelectedJobArray(_ jobs: [JobOccupation]) /// 로딩 상태를 설정합니다 /// - Parameter status: 설정할 로딩 상태 func setLoading(status: Bool)Projects/App/Sources/Navigation/NavigationStack.swift (1)
61-62
: 이상형 정보 입력 인트로 화면 네비게이션이 기존 구조와 일관성있게 구현되었습니다.
DreamPartnerIntroView
로의 네비게이션이 기존 패턴을 따르고 있으며, 이상형 정보 입력 플로우의 시작점으로 적절히 배치되었습니다.다만, 사용자 경험 관점에서 한 가지 제안드립니다:
인트로 화면에서 다음 화면으로의 자동 전환 시 적절한 타이밍 조절이 필요할 수 있습니다. 사용자가 화면의 내용을 충분히 인지할 수 있는 시간이 보장되어야 합니다.
Projects/Features/SignUp/Sources/DreamPartnerInput/DreamPartnerIntro/DreamPartnerIntroView.swift (3)
17-23
: 상태 관리 로직에 대한 문서화가 필요합니다.MVIContainer와 상태 변수들의 목적과 사용법에 대한 주석을 추가하면 코드의 가독성과 유지보수성이 향상될 것 같습니다.
다음과 같은 형식의 문서화를 추가해보세요:
+/// MVI 아키텍처를 위한 컨테이너 @StateObject var container: MVIContainer<DreamPartnerIntroIntent.Intentable, DreamPartnerIntroModel.Stateful> +/// 아이콘 애니메이션을 위한 상태 변수 @State var isShowIcon: Bool = false +/// 텍스트 애니메이션을 위한 상태 변수 @State var isShowText: Bool = false
25-37
: 초기화 로직을 더 간단하게 개선할 수 있습니다.현재 구현은 정상적으로 작동하지만, 타입 캐스팅을 줄이고 가독성을 개선할 수 있습니다.
다음과 같이 개선해보세요:
public init(_ input: SignUpFormDomain) { - let model = DreamPartnerIntroModel() - let intent = DreamPartnerIntroIntent( - model: model, - input: .init(input: input) - ) - let container = MVIContainer( - intent: intent as DreamPartnerIntroIntent.Intentable, - model: model as DreamPartnerIntroModel.Stateful, - modelChangePublisher: model.objectWillChange - ) + let model = DreamPartnerIntroModel() + let intent = DreamPartnerIntroIntent(model: model, input: .init(input: input)) + let container = MVIContainer(intent: intent, model: model) self._container = StateObject(wrappedValue: container) }
90-94
: 프리뷰 케이스를 다양화하면 좋을 것 같습니다.현재는 기본 케이스만 프리뷰하고 있습니다. 다양한 상황에서의 UI를 확인할 수 있도록 프리뷰를 확장하면 좋을 것 같습니다.
다음과 같이 개선해보세요:
#Preview { - NavigationView { - DreamPartnerIntroView(.mock) + Group { + NavigationView { + DreamPartnerIntroView(.mock) + } + .previewDisplayName("기본 상태") + + NavigationView { + DreamPartnerIntroView(.mock) + } + .preferredColorScheme(.dark) + .previewDisplayName("다크 모드") } }Projects/Core/CommonKit/Sources/AppCoordinator.swift (1)
126-131
: 로그아웃 구현이 기본적으로 잘 되어있습니다만, 몇 가지 개선사항이 있습니다.기본적인 토큰 제거와 상태 변경은 잘 구현되어 있습니다. 하지만 다음과 같은 개선사항을 제안드립니다:
- 다른 메서드들처럼 메인 스레드에서 상태를 변경하도록 수정
- 토큰 제거 실패에 대한 에러 처리 추가
- 로그아웃 이벤트 로깅 추가
다음과 같이 개선하는 것을 추천드립니다:
- public func logout() { - TokenManager.accessToken = nil - TokenManager.refreshToken = nil - TokenManager.registerToken = nil - AuthState.change(.loggedOut) + public func logout() { + do { + // 토큰 제거 + TokenManager.accessToken = nil + TokenManager.refreshToken = nil + TokenManager.registerToken = nil + + // 로그아웃 이벤트 로깅 + print("👤 User logged out successfully") + + // 메인 스레드에서 상태 변경 + DispatchQueue.main.async { + AuthState.change(.loggedOut) + } + } catch { + print("❌ Failed to logout: \(error)") + } + }Projects/Features/SignUp/Sources/ProfileInput/AuthProfileAge/AuthProfileAgeInputView.swift (1)
Line range hint
1-150
: 사용자 경험 개선을 위한 제안사항다음과 같은 개선사항들을 고려해보시면 좋을 것 같습니다:
- 키보드가 나타날 때 자동으로 스크롤되어 입력 필드가 가려지지 않도록 처리
- 사용자가 잘못된 연도를 입력했을 때 즉각적인 피드백 제공
- 툴팁이 표시될 때 배경을 어둡게 처리하여 포커스 강조
다음과 같이 수정해보시는 건 어떨까요:
public var body: some View { VStack { ProfileInputTemplatedView( currentPage: 2, maxPage: 5, subMessage: "좋은 \(state.targetGender.name)분 소개시켜 드릴께요!", mainMessage: "당신의 나이는 무엇인가요?" ) { + ScrollViewReader { proxy in VStack { HStack { VerifyCodeInputView( verifyCode: $container.model.birthYear, errorMessage: $container.model.errorMessage, verifyCodeMaxCount: 4, boxHeight: 92, textColor: .black, borderWidth: 4, borderColor: .white, backColor: DesignCore.Colors.yellow50, cornerRadius: 20, focused: _isFocused ) .padding(.horizontal, 6) .onChange(of: state.birthYear) { intent.onYearChanged( state.birthYear ) + if !state.isValidYear { + withAnimation { + proxy.scrollTo("yearInput", anchor: .center) + } + } } + .id("yearInput") } } + } } + .background( + Color.black.opacity(state.isShowToolTip ? 0.3 : 0) + .ignoresSafeArea() + .animation(.easeInOut, value: state.isShowToolTip) + ) } }Projects/App/Sources/Debug/AuthInfoView.swift (3)
158-165
: 로그아웃 작업 시 확인 다이얼로그 추가 필요사용자의 실수를 방지하기 위해 로그아웃 전에 확인 다이얼로그를 표시하는 것이 좋습니다.
다음과 같이 수정하는 것을 제안합니다:
.toolbar { ToolbarItem(placement: .topBarTrailing) { - Button("로그아웃", role: .destructive) { - AppCoordinator.shared.logout() - } + Button("로그아웃", role: .destructive) { + showLogoutAlert = true + } + .alert("로그아웃", isPresented: $showLogoutAlert) { + Button("취소", role: .cancel) { } + Button("로그아웃", role: .destructive) { + AppCoordinator.shared.logout() + } + } message: { + Text("정말 로그아웃 하시겠습니까?") + } } }
Line range hint
1-165
: 디버그 뷰의 보안 강화 필요민감한 정보를 다루는 디버그 뷰에 대한 몇 가지 보안 개선사항을 제안드립니다:
- 토큰 값 표시 시 마스킹 처리
- 클립보드에 복사된 민감 정보의 자동 삭제 타이머 추가
- 디버그 뷰 접근 시 개발자 인증 추가
이러한 보안 기능을 구현하는데 도움이 필요하시다면 말씀해 주세요.
Line range hint
14-157
: 데이터 관리 구조 개선 제안현재 구조에 대한 개선 제안사항입니다:
TableInfoModel
을 별도 파일로 분리- 각 섹션의 데이터 소스를 별도 타입으로 분리하여 관리
AppCoordinator
의존성을 주입 방식으로 변경이는 다음과 같은 이점이 있습니다:
- 코드의 모듈성 향상
- 테스트 용이성 증가
- 유지보수성 개선
구체적인 리팩토링 방안이 필요하시다면 말씀해 주세요.
Projects/Features/SignUp/Sources/DreamPartnerInput/DreamPartnerAge/DreamPartnerAgeView.swift (2)
Line range hint
156-186
: 연령 입력 유효성 검사 및 접근성 개선 필요현재 구현에서 다음 사항들의 보완이 필요해 보입니다:
- 상한/하한 나이 범위에 대한 유효성 검사 로직 추가
- 선택 가능한 나이 범위에 대한 사용자 안내
- VoiceOver 지원을 위한 접근성 레이블 추가
다음과 같은 개선사항을 제안드립니다:
func ageUpDownView(type: AgeUpDownType) -> some View { HStack(spacing: 8) { HStack { Text(type.imoji) Text("내 나이보다") Text(type.text) Text("로") - } + }.accessibilityElement(combinedLabel: true) + .accessibilityLabel("\(type == .up ? "상한" : "하한") 나이 설정") // ... 나머지 코드 } }
Line range hint
193-211
: BottomSheetPickerView 구현 개선 필요피커 구현에서 다음 사항들을 검토해주세요:
- 0-15 범위가 충분한지 검토 필요 (실제 나이 차이 범위가 더 클 수 있음)
- "상관없어요" 옵션의 위치가 직관적인지 검토
- 선택된 값에 대한 즉각적인 피드백 추가
더 넓은 범위를 지원하도록 수정을 제안드립니다:
Picker("숫자 선택", selection: $selectedValue) { Text("상관없어요") .tag(String?.none) - ForEach(0...15, id: \.self) { number in + ForEach(0...30, id: \.self) { number in Text("\(number)") .tag(String?(String(number))) } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (6)
Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/heart-with-arrow.imageset/heart-with-arrow.png
is excluded by!**/*.png
Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/heart-with-arrow.imageset/heart-with-arrow@2x.png
is excluded by!**/*.png
Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/heart-with-arrow.imageset/heart-with-arrow@3x.png
is excluded by!**/*.png
Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/magnifying-glass.imageset/magnifying-glass.png
is excluded by!**/*.png
Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/magnifying-glass.imageset/magnifying-glass@2x.png
is excluded by!**/*.png
Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/magnifying-glass.imageset/magnifying-glass@3x.png
is excluded by!**/*.png
📒 Files selected for processing (18)
Projects/App/Sources/Debug/AuthInfoView.swift
(1 hunks)Projects/App/Sources/Navigation/NavigationStack.swift
(2 hunks)Projects/Core/CommonKit/Sources/AppCoordinator.swift
(1 hunks)Projects/Core/CommonKit/Sources/Path/PathTypes.swift
(7 hunks)Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/heart-with-arrow.imageset/Contents.json
(1 hunks)Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/magnifying-glass.imageset/Contents.json
(1 hunks)Projects/Features/SignUp/Sources/AuthSignUp/AuthAgreement/AuthAgreementIntent.swift
(1 hunks)Projects/Features/SignUp/Sources/DreamPartnerInput/DreamPartnerAge/DreamPartnerAgeView.swift
(1 hunks)Projects/Features/SignUp/Sources/DreamPartnerInput/DreamPartnerIntro/DreamPartnerIntroIntent.swift
(1 hunks)Projects/Features/SignUp/Sources/DreamPartnerInput/DreamPartnerIntro/DreamPartnerIntroModel.swift
(1 hunks)Projects/Features/SignUp/Sources/DreamPartnerInput/DreamPartnerIntro/DreamPartnerIntroView.swift
(1 hunks)Projects/Features/SignUp/Sources/DreamPartnerInput/DreamPartnerIntro/DreamPartnerJobModel.swift
(1 hunks)Projects/Features/SignUp/Sources/ProfileInput/AuthName/AuthNameInputIntent.swift
(1 hunks)Projects/Features/SignUp/Sources/ProfileInput/AuthProfileAge/AuthProfileAgeInputView.swift
(1 hunks)Projects/Features/SignUp/Sources/ProfileInput/AuthProfileGenderInput/AuthProfileGenderInputView.swift
(1 hunks)Projects/Features/SignUp/Sources/ProfileInput/ProfileIntro/ProfileIntroIntent.swift
(1 hunks)Projects/Features/SignUp/Sources/ProfileInput/ProfileIntro/ProfileIntroModel.swift
(1 hunks)Projects/Features/SignUp/Sources/ProfileInput/ProfileIntro/ProfileIntroView.swift
(1 hunks)
✅ Files skipped from review due to trivial changes (3)
- Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/heart-with-arrow.imageset/Contents.json
- Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/magnifying-glass.imageset/Contents.json
- Projects/Features/SignUp/Sources/ProfileInput/AuthProfileGenderInput/AuthProfileGenderInputView.swift
🧰 Additional context used
📓 Learnings (1)
Projects/Features/SignUp/Sources/DreamPartnerInput/DreamPartnerIntro/DreamPartnerIntroIntent.swift (1)
Learnt from: jisu15-kim
PR: Student-Center/3days-ios#32
File: Projects/Features/SignUp/Sources/DreamPartnerInput/DreamPartnerAge/DreamPartnerAgeIntent.swift:28-42
Timestamp: 2024-11-12T13:22:13.201Z
Learning: 프로젝트에서 Intent 클래스의 `Intentable` 프로토콜을 정의할 때, 개발자가 의도적으로 클래스의 extension 내부에 프로토콜을 정의하는 경우가 있습니다.
🪛 SwiftLint
Projects/Features/SignUp/Sources/DreamPartnerInput/DreamPartnerIntro/DreamPartnerIntroIntent.swift
[Warning] 14-14: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 34-34: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 51-51: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 14-14: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 34-34: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 51-51: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
Projects/Features/SignUp/Sources/DreamPartnerInput/DreamPartnerIntro/DreamPartnerIntroModel.swift
[Warning] 15-15: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 28-28: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 42-42: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 15-15: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 28-28: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 42-42: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
Projects/Features/SignUp/Sources/DreamPartnerInput/DreamPartnerIntro/DreamPartnerJobModel.swift
[Warning] 16-16: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 30-30: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 47-47: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 16-16: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 30-30: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 47-47: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
Projects/Features/SignUp/Sources/ProfileInput/ProfileIntro/ProfileIntroIntent.swift
[Warning] 14-14: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 34-34: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 51-51: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 14-14: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 34-34: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 51-51: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
Projects/Features/SignUp/Sources/ProfileInput/ProfileIntro/ProfileIntroModel.swift
[Warning] 15-15: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 28-28: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 42-42: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 15-15: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 28-28: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 42-42: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
🔇 Additional comments (11)
Projects/Features/SignUp/Sources/AuthSignUp/AuthAgreement/AuthAgreementIntent.swift (2)
56-56
: 네비게이션 플로우 변경이 적절해 보입니다.
동의 화면에서 프로필 입력 인트로 화면으로의 전환이 PR의 목적과 잘 부합합니다.
56-56
: 새로운 네비게이션 경로 검증이 필요합니다.
.profileIntro
케이스가 올바르게 구현되어 있는지 확인이 필요합니다.
✅ Verification successful
프로필 인트로 네비게이션 경로가 올바르게 구현되어 있습니다.
PathTypes.swift
에profileIntro
케이스가 정의되어 있고 필요한 입력값(SignUpFormDomain
)을 받도록 구현되어 있습니다.ProfileIntroView.swift
파일이 존재하며,NavigationStack.swift
에서 해당 뷰로의 네비게이션이 적절히 처리되고 있습니다.- 네비게이션 스택에서
.profileIntro
케이스에 대한 라우팅이ProfileIntroView
로 올바르게 연결되어 있습니다.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the implementation of .profileIntro case and related views
# Check if ProfileIntro case exists in PathType
rg -A 5 "case profileIntro"
# Check if ProfileIntroView exists
fd "ProfileIntroView"
# Check coordinator handling of profileIntro
rg -A 5 "case .profileIntro"
Length of output: 2419
Projects/Features/SignUp/Sources/DreamPartnerInput/DreamPartnerIntro/DreamPartnerIntroIntent.swift (1)
51-66
:
프로토콜 구현부 개선 필요
구현부에서 다음 사항들을 검토해주세요:
onTapNextButton()
이 비어있는데, 이는 의도적인 것인지 확인이 필요합니다.pushNextView()
가 실패할 경우에 대한 에러 처리가 없습니다.
onTapNextButton()
의 구현이 필요한지 확인하기 위해 다음 스크립트를 실행합니다:
에러 처리를 위해 다음과 같은 수정을 제안드립니다:
@MainActor
func pushNextView() async {
+ do {
AppCoordinator.shared.changeRootView(
.signUp(.dreamPartnerAgeRange(input: input.input))
)
+ } catch {
+ // TODO: 에러 처리 추가 필요
+ model?.handleError(error)
+ }
}
🧰 Tools
🪛 SwiftLint
[Warning] 51-51: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 51-51: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
Projects/App/Sources/Navigation/NavigationStack.swift (1)
43-44
: 프로필 인트로 화면 네비게이션 추가가 적절히 구현되었습니다.
기존 네비게이션 패턴을 잘 따르고 있으며, 회원가입 플로우에 자연스럽게 통합되었습니다.
Projects/Features/SignUp/Sources/DreamPartnerInput/DreamPartnerIntro/DreamPartnerIntroView.swift (1)
9-13
: 필요한 모듈들이 적절히 임포트되어 있습니다.
SwiftUI 기반 뷰 구현에 필요한 모든 의존성이 명확하게 정의되어 있습니다.
Projects/Core/CommonKit/Sources/Path/PathTypes.swift (3)
55-56
: 디버그 프리뷰 타입이 적절히 추가되었습니다!
디버그 환경에서 새로운 화면을 미리보기 할 수 있도록 잘 구성되어 있습니다.
73-74
: 화면 이름이 일관성 있게 추가되었습니다!
각 화면의 한글 이름이 기존 네이밍 패턴을 잘 따르고 있으며, 사용자가 이해하기 쉽게 작성되었습니다.
Also applies to: 83-86
97-97
: 회원가입 플로우가 체계적으로 구성되었습니다!
프로필 입력과 이상형 정보 입력 플로우가 순차적으로 잘 구성되어 있습니다. 각 단계별로 SignUpFormDomain
을 일관되게 사용하여 데이터 흐름이 명확합니다.
Also applies to: 106-109
Projects/Features/SignUp/Sources/ProfileInput/AuthProfileAge/AuthProfileAgeInputView.swift (2)
140-141
: 네비게이션 처리 방식이 개선되었습니다.
기존의 showLeftBackButton
대신 setPopNavigation
을 사용하여 일관된 네비게이션 흐름을 구현한 것이 좋습니다. AppCoordinator
를 통한 중앙 집중식 네비게이션 관리는 앱의 일관성을 높여줄 것입니다.
Line range hint 20-41
: SignUpFormDomain 의존성 검증 필요
현재 뷰는 SignUpFormDomain
을 입력으로 받아 초기화되고 있습니다. 이 도메인 모델의 변경이 뷰에 영향을 줄 수 있으므로 의존성을 확인해야 합니다.
✅ Verification successful
Let's gather more information about the SignUpFormDomain model's structure and its usage in AuthProfileAgeInputView.
SignUpFormDomain 의존성 검증 완료
AuthProfileAgeInputView는 SignUpFormDomain을 안전하게 사용하고 있습니다:
- 입력받은 나이 정보를 SignUpFormDomain의 profile.birthYear에만 저장
- 다음 화면으로 이동 시 수정된 도메인 객체를 전달
- 읽기 작업은 gender 정보 확인에만 제한적으로 사용
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# SignUpFormDomain 모델의 사용처와 의존성을 확인합니다.
# 모델 정의 검색
echo "Searching for SignUpFormDomain definition..."
rg -p "struct SignUpFormDomain" --type swift
# 모델 사용처 검색
echo "Searching for SignUpFormDomain usage..."
rg -p "SignUpFormDomain" --type swift
Length of output: 5692
Script:
#!/bin/bash
# SignUpFormDomain 모델의 구조와 AuthProfileAgeInputView에서의 사용을 확인합니다.
# SignUpFormDomain 모델 구조 확인
echo "Checking SignUpFormDomain structure..."
cat "Projects/Model/Model/Sources/SignUp/Domain/SignUpFormDomain.swift"
# AuthProfileAgeInputView에서의 사용 확인
echo -e "\nChecking AuthProfileAgeInputView usage..."
cat "Projects/Features/SignUp/Sources/ProfileInput/AuthProfileAge/AuthProfileAgeInputView.swift"
# AuthProfileAgeInputIntent에서의 사용 확인
echo -e "\nChecking AuthProfileAgeInputIntent usage..."
cat "Projects/Features/SignUp/Sources/ProfileInput/AuthProfileAge/AuthProfileAgeInputIntent.swift"
Length of output: 12236
Projects/Features/SignUp/Sources/DreamPartnerInput/DreamPartnerAge/DreamPartnerAgeView.swift (1)
140-142
: 뒤로 가기 버튼 제거에 대한 UX 검토 필요
뒤로 가기 버튼을 숨기는 것은 사용자의 네비게이션 경험에 영향을 줄 수 있습니다. 다음 사항들을 고려해주세요:
- 사용자가 이전 화면으로 돌아가는 방법을 명확히 인지할 수 있는지
- 프로필 입력 과정에서 실수로 잘못 입력했을 때의 수정 방법
Task { | ||
try? await Task.sleep(for: .milliseconds(2500)) | ||
await pushNextView() | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Task 생명주기 관리 및 에러 처리 개선 필요
초기화 시 시작되는 Task에 대해 다음 사항들을 고려해주세요:
- Task 취소 처리가 없어 메모리 누수가 발생할 수 있습니다.
- 하드코딩된 2.5초 지연은 사용자 경험에 일관성이 없을 수 있습니다.
- Task.sleep의 에러 처리가 무시되고 있습니다.
다음과 같이 개선을 제안합니다:
class ProfileIntroIntent {
private weak var model: ProfileIntroModelActionable?
private let input: DataModel
+ private var transitionTask: Task<Void, Never>?
// MARK: Life cycle
init(
model: ProfileIntroModelActionable,
input: DataModel
) {
self.input = input
self.model = model
- Task {
- try? await Task.sleep(for: .milliseconds(2500))
- await pushNextView()
- }
+ startTransitionTimer()
+ }
+
+ private func startTransitionTimer() {
+ transitionTask = Task {
+ do {
+ try await Task.sleep(for: .milliseconds(2500))
+ if !Task.isCancelled {
+ await pushNextView()
+ }
+ } catch {
+ print("Transition timer interrupted: \(error)")
+ }
+ }
+ }
+
+ deinit {
+ transitionTask?.cancel()
}
📝 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.
Task { | |
try? await Task.sleep(for: .milliseconds(2500)) | |
await pushNextView() | |
} | |
} | |
class ProfileIntroIntent { | |
private weak var model: ProfileIntroModelActionable? | |
private let input: DataModel | |
private var transitionTask: Task<Void, Never>? | |
// MARK: Life cycle | |
init( | |
model: ProfileIntroModelActionable, | |
input: DataModel | |
) { | |
self.input = input | |
self.model = model | |
startTransitionTimer() | |
} | |
private func startTransitionTimer() { | |
transitionTask = Task { | |
do { | |
try await Task.sleep(for: .milliseconds(2500)) | |
if !Task.isCancelled { | |
await pushNextView() | |
} | |
} catch { | |
print("Transition timer interrupted: \(error)") | |
} | |
} | |
} | |
deinit { | |
transitionTask?.cancel() | |
} | |
} |
//MARK: - Intent | ||
class DreamPartnerIntroIntent { | ||
private weak var model: DreamPartnerIntroModelActionable? | ||
private let input: DataModel | ||
|
||
// MARK: Life cycle | ||
init( | ||
model: DreamPartnerIntroModelActionable, | ||
input: DataModel | ||
) { | ||
self.input = input | ||
self.model = model | ||
|
||
Task { | ||
try? await Task.sleep(for: .milliseconds(2500)) | ||
await pushNextView() | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
초기화 시 자동 전환 로직 검토 필요
Task 내에서 sleep을 사용하여 지연된 화면 전환을 구현하고 있습니다. 다음 사항들을 고려해주세요:
- 사용자가 화면을 벗어나거나 앱이 백그라운드로 전환될 때 Task가 적절히 취소되어야 합니다.
- 화면 전환 시간(2.5초)을 상수로 분리하는 것이 좋습니다.
- Task.sleep 대신 더 안전한 방법을 고려해볼 수 있습니다.
다음과 같이 수정하는 것을 제안드립니다:
+ private let transitionDelay: Double = 2.5
+ private var transitionTask: Task<Void, Error>?
init(
model: DreamPartnerIntroModelActionable,
input: DataModel
) {
self.input = input
self.model = model
- Task {
+ transitionTask = Task {
try? await Task.sleep(for: .milliseconds(2500))
await pushNextView()
}
}
+ deinit {
+ transitionTask?.cancel()
+ }
Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 SwiftLint
[Warning] 14-14: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 14-14: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
func showErrorView(error: ErrorModel) { | ||
showErrorView = error | ||
} | ||
func showErrorAlert(error: ErrorModel) { | ||
showErrorAlert = error | ||
} | ||
func resetError() { | ||
showErrorView = nil | ||
showErrorAlert = nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
에러 처리 메서드의 스레드 안전성 개선 필요
에러 상태를 변경하는 메서드들이 메인 스레드에서 실행되도록 보장하면 좋을 것 같습니다.
다음과 같이 수정하는 것을 제안합니다:
func showErrorView(error: ErrorModel) {
- showErrorView = error
+ DispatchQueue.main.async {
+ self.showErrorView = error
+ }
}
func showErrorAlert(error: ErrorModel) {
- showErrorAlert = error
+ DispatchQueue.main.async {
+ self.showErrorAlert = error
+ }
}
func resetError() {
- showErrorView = nil
- showErrorAlert = nil
+ DispatchQueue.main.async {
+ self.showErrorView = nil
+ self.showErrorAlert = nil
+ }
}
📝 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.
func showErrorView(error: ErrorModel) { | |
showErrorView = error | |
} | |
func showErrorAlert(error: ErrorModel) { | |
showErrorAlert = error | |
} | |
func resetError() { | |
showErrorView = nil | |
showErrorAlert = nil | |
} | |
func showErrorView(error: ErrorModel) { | |
DispatchQueue.main.async { | |
self.showErrorView = error | |
} | |
} | |
func showErrorAlert(error: ErrorModel) { | |
DispatchQueue.main.async { | |
self.showErrorAlert = error | |
} | |
} | |
func resetError() { | |
DispatchQueue.main.async { | |
self.showErrorView = nil | |
self.showErrorAlert = nil | |
} | |
} |
colors: [ | ||
.init(hex: 0xF3DDE5).opacity(0.0), | ||
.init(hex: 0xF3DDE5) | ||
], | ||
startPoint: .top, | ||
endPoint: .bottom | ||
) | ||
.frame(height: Device.height * 0.5) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
상수값들의 분리가 필요합니다.
하드코딩된 색상값과 크기값들을 상수로 분리하면 유지보수성이 향상될 것 같습니다.
다음과 같이 개선해보세요:
+private enum Constants {
+ static let gradientStartColor = Color(hex: 0xF3DDE5)
+ static let gradientHeight: CGFloat = Device.height * 0.5
+}
LinearGradient(
colors: [
- .init(hex: 0xF3DDE5).opacity(0.0),
- .init(hex: 0xF3DDE5)
+ Constants.gradientStartColor.opacity(0.0),
+ Constants.gradientStartColor
],
startPoint: .top,
endPoint: .bottom
)
-.frame(height: Device.height * 0.5)
+.frame(height: Constants.gradientHeight)
📝 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.
colors: [ | |
.init(hex: 0xF3DDE5).opacity(0.0), | |
.init(hex: 0xF3DDE5) | |
], | |
startPoint: .top, | |
endPoint: .bottom | |
) | |
.frame(height: Device.height * 0.5) | |
private enum Constants { | |
static let gradientStartColor = Color(hex: 0xF3DDE5) | |
static let gradientHeight: CGFloat = Device.height * 0.5 | |
} | |
LinearGradient( | |
colors: [ | |
Constants.gradientStartColor.opacity(0.0), | |
Constants.gradientStartColor | |
], | |
startPoint: .top, | |
endPoint: .bottom | |
) | |
.frame(height: Constants.gradientHeight) |
.task { | ||
await intent.task() | ||
try? await Task.sleep(for: .milliseconds(250)) | ||
isShowIcon = true | ||
try? await Task.sleep(for: .milliseconds(150)) | ||
isShowText = true | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Task.sleep 사용에 대한 개선이 필요합니다.
애니메이션 타이밍을 위해 Task.sleep을 사용하는 것은 다음과 같은 문제가 있습니다:
- 사용자 경험에 일관성이 없을 수 있습니다
- 디바이스 성능에 따라 다르게 동작할 수 있습니다
- 테스트하기 어려운 구조입니다
애니메이션 로직을 다음과 같이 개선하는 것을 추천드립니다:
-.task {
- await intent.task()
- try? await Task.sleep(for: .milliseconds(250))
- isShowIcon = true
- try? await Task.sleep(for: .milliseconds(150))
- isShowText = true
-}
+.task {
+ await intent.task()
+ withAnimation(.easeInOut(duration: 0.25)) {
+ isShowIcon = true
+ }
+ withAnimation(.easeInOut(duration: 0.15).delay(0.25)) {
+ isShowText = true
+ }
+}
📝 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.
.task { | |
await intent.task() | |
try? await Task.sleep(for: .milliseconds(250)) | |
isShowIcon = true | |
try? await Task.sleep(for: .milliseconds(150)) | |
isShowText = true | |
} | |
.task { | |
await intent.task() | |
withAnimation(.easeInOut(duration: 0.25)) { | |
isShowIcon = true | |
} | |
withAnimation(.easeInOut(duration: 0.15).delay(0.25)) { | |
isShowText = true | |
} | |
} |
case .profileIntro: | ||
hasher.combine(-1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
해시 값 할당 방식의 개선이 필요합니다.
현재 인트로 화면들에 대해 음수 값(-1, -2)을 사용하고 있는데, 이는 기존의 양수 시퀀스 패턴과 일치하지 않습니다. 유지보수성을 높이기 위해 일관된 번호 체계를 사용하는 것이 좋습니다.
다음과 같이 수정하는 것을 제안드립니다:
case .profileIntro:
- hasher.combine(-1)
+ hasher.combine(13)
case .dreamPartnerIntro:
- hasher.combine(-2)
+ hasher.combine(14)
Also applies to: 140-141
.animation(.easeInOut, value: isShowIcon) | ||
.animation(.easeInOut, value: isShowText) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
.animation Modifier의 사용 방법 업데이트 필요
iOS 15부터 .animation(_:value:)
Modifier는 폐기되었습니다. 대신 상태 변화 시 withAnimation
블록을 사용해 애니메이션을 적용해 주세요.
코드 수정 제안:
- .animation(.easeInOut, value: isShowIcon)
- .animation(.easeInOut, value: isShowText)
상태 변경 시 withAnimation
사용:
withAnimation(.easeInOut) {
isShowIcon = true
}
.task { | ||
await intent.task() | ||
try? await Task.sleep(for: .milliseconds(250)) | ||
isShowIcon = true | ||
try? await Task.sleep(for: .milliseconds(150)) | ||
isShowText = true | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Task.sleep(for:)
의 호환성 확인 필요
Task.sleep(for:)
메소드는 iOS 16 이상에서만 지원됩니다. 최소 지원 버전이 iOS 15 이하라면 Task.sleep(nanoseconds:)
를 사용하는 것이 좋습니다.
코드 수정 제안:
- try? await Task.sleep(for: .milliseconds(250))
+ try? await Task.sleep(nanoseconds: UInt64(250_000_000))
Committable suggestion skipped: line range outside the PR's diff.
구현사항
스크린샷(선택)
Summary by CodeRabbit
새로운 기능
버그 수정
문서화