-
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-121] 홈 - 프로필 탭 구현 #39
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: 14
🧹 Outside diff range and nitpick comments (31)
Projects/Core/CoreKit/Sources/Int+Ext.swift (2)
1-8
: 파일 헤더 주석이 불완전합니다.파일의 목적과 사용 사례를 설명하는 문서화가 필요합니다.
다음과 같이 개선하는 것을 추천드립니다:
// // Int+Ext.swift // CoreKit // +// 정수형을 프로필 뷰에서 표시 가능한 형태로 변환하기 위한 확장입니다. // // Created by 김지수 on 11/3/24. // Copyright © 2024 com.weave. All rights reserved. //
9-10
: 불필요한 import 문이 있습니다.현재 구현에서는
Foundation
import가 필요하지 않습니다.String
타입은 Swift 표준 라이브러리에 포함되어 있습니다.-import Foundation
Projects/Features/Home/Sources/Profile/ProfileIntent.swift (2)
14-27
: 문서화 개선이 필요합니다클래스의 목적과 책임을 명확히 하기 위해 문서화를 추가하는 것이 좋겠습니다.
다음과 같이 문서화를 추가해보세요:
+/// 프로필 화면의 사용자 인터랙션을 처리하는 Intent 클래스입니다. +/// - Note: MVVM 아키텍처의 ViewModel과 유사한 역할을 수행합니다. class ProfileIntent { private weak var model: ProfileModelActionable? private let input: DataModel🧰 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)
14-14
: MARK 주석 형식을 수정해주세요SwiftLint 규칙에 따라 MARK 주석 형식을 수정해야 합니다.
다음과 같이 수정해주세요:
-//MARK: - Intent +// MARK: - Intent -//MARK: - Intentable +// MARK: - Intentable -//MARK: - Intentable +// MARK: - IntentableAlso applies to: 29-29, 45-45
🧰 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/Home/Sources/ProfilePannel/ProfilePannelIntent.swift (3)
14-14
: MARK 주석 형식을 수정해주세요SwiftLint 규칙에 맞게 MARK 주석 형식을 수정해야 합니다.
-//MARK: - Intent +// MARK: - Intent🧰 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)
31-38
: 프로토콜 메서드에 문서화가 필요합니다각 메서드의 목적과 동작을 설명하는 문서 주석을 추가해주세요. 특히
onTapNextButton
,onAppear
,task
의 역할과 사용 시점을 명확히 해야 합니다.protocol Intentable { - // content + /// 다음 버튼 탭 시 호출되는 메서드 func onTapNextButton() - // default + /// 뷰가 나타날 때 호출되는 메서드 func onAppear() + /// 비동기 작업을 처리하는 메서드 func task() async }
49-52
: 에러 처리 로직 추가 필요
setProfile
과setName
메서드 호출 시 발생할 수 있는 실패 케이스에 대한 처리가 없습니다. 모델이 nil이 되었거나 설정에 실패했을 경우의 처리를 추가하는 것이 좋겠습니다.func onAppear() { + guard let model = model else { + // 에러 처리 또는 로깅 + return + } - model?.setProfile(profile: input.profile) - model?.setName(name: input.name) + model.setProfile(profile: input.profile) + model.setName(name: input.name) }Projects/Features/Home/Sources/HomeMain/HomeMainIntent.swift (1)
15-15
: 코드 스타일 개선 필요SwiftLint 경고에 따라 MARK 주석 형식을 수정해주세요.
-//MARK: - Intent +// MARK: - Intent🧰 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/App/Sources/Navigation/NavigationStack.swift (1)
31-32
: 코드 변경이 적절해 보입니다만, 문서화가 필요합니다.
userInfo
파라미터를 통해 사용자 정보를 전달하는 구현이 잘 되어있습니다. 하지만 이 변경사항에 대한 문서화를 추가하면 좋을 것 같습니다.다음과 같이 문서 주석을 추가하는 것을 제안합니다:
+ /// 홈 화면을 표시하며, 사용자 정보를 전달합니다. + /// - Parameter userInfo: 표시할 사용자 정보 case .home(let userInfo): HomeMainView(userInfo: userInfo)Projects/Features/Home/Sources/HomeMain/HomeMainModel.swift (2)
65-67
: 사용자 정보 설정 시 유효성 검사 추가를 고려해주세요.현재 구현은 단순히 값을 할당하고 있습니다. 사용자 정보의 무결성을 보장하기 위해 유효성 검사 로직 추가를 제안드립니다.
func setUserInfo(userInfo: UserInfo) { + // 필수 필드 검증 + guard !userInfo.id.isEmpty else { + return + } self.userInfo = userInfo }
16-16
: MARK 주석 형식을 수정해주세요.Swift 스타일 가이드에 따라 MARK 주석 형식을 수정하는 것이 좋습니다.
- //MARK: Stateful + // MARK: - Stateful🧰 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)
Projects/Features/Home/Sources/Profile/ProfileModel.swift (3)
14-43
: 문서화 개선이 필요합니다.
Stateful
프로토콜과 각 프로퍼티에 대한 문서화 주석을 추가하면 코드의 가독성과 유지보수성이 향상될 것 같습니다.다음과 같이 문서화를 추가해보세요:
protocol Stateful { + /// 사용자 정보 모델 var userInfoModel: UserInfo? { get } + /// 유효성 검증 상태 var isValidated: Bool { get } + /// 로딩 상태 var isLoading: Bool { get } + /// 에러 뷰 표시 모델 var showErrorView: ErrorModel? { get } + /// 에러 알림 표시 모델 var showErrorAlert: ErrorModel? { get } }🧰 Tools
🪛 SwiftLint
[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] 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)
16-16
: MARK 주석 형식을 수정해주세요.SwiftLint 경고에 따라 MARK 주석 형식을 수정해야 합니다.
다음과 같이 수정해주세요:
- //MARK: Stateful + // MARK: - Stateful - //MARK: State Properties + // MARK: - State Properties -//MARK: - Actionable +// MARK: - ActionableAlso applies to: 30-30, 45-45
🧰 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)
62-67
: 입력값 검증이 필요합니다.
setUserInfo
와setValidation
메서드에 입력값 검증 로직을 추가하면 좋을 것 같습니다.다음과 같이 수정해보세요:
func setUserInfo(_ userInfo: UserInfo) { + guard userInfo.isValid else { + showErrorAlert(error: .init(message: "잘못된 사용자 정보입니다.")) + return + } userInfoModel = userInfo }Projects/Features/Home/Sources/ProfilePannel/ProfilePannelModel.swift (4)
1-13
: 파일 이름 오타 수정 필요파일 이름에 오타가 있습니다. "Pannel"을 "Panel"로 수정해 주세요. 이는 영어 철자의 정확성을 위해 필요합니다.
14-30
: 프로토콜 문서화 및 MARK 포맷팅 개선 필요
Stateful
프로토콜의 각 프로퍼티에 대한 문서화 주석이 필요합니다.- MARK 주석 포맷을 표준 형식으로 수정해야 합니다.
다음과 같이 수정해 주세요:
- //MARK: Stateful + // MARK: - Stateful + /// 사용자 프로필 상태를 관리하는 프로토콜 protocol Stateful { + /// 사용자 이름 var name: String? { get } + /// 사용자 프로필 정보 var profile: UserInfoProfile? { 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)
31-43
: 불필요한 옵셔널 초기화 제거옵셔널 변수의 기본값은 자동으로
nil
이므로, 명시적인nil
초기화는 불필요합니다.다음과 같이 수정해 주세요:
- @Published var name: String? = nil - @Published var profile: UserInfoProfile? = nil + @Published var name: String? + @Published var profile: UserInfoProfile?🧰 Tools
🪛 SwiftLint
[Warning] 31-31: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 31-31: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 33-33: Initializing an optional variable with nil is redundant
(redundant_optional_initialization)
[Warning] 34-34: Initializing an optional variable with nil is redundant
(redundant_optional_initialization)
14-91
: 테스트 용이성 개선 필요현재 구현은 MVVM 패턴을 잘 따르고 있지만, 테스트 용이성 측면에서 몇 가지 개선이 필요합니다:
- 프로토콜 기반 의존성 주입 구현
- 테스트를 위한 모의 객체(Mock) 추가
- 상태 변경에 대한 단위 테스트 추가
테스트 구현에 도움이 필요하시다면 말씀해 주세요.
🧰 Tools
🪛 SwiftLint
[Warning] 16-16: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 31-31: 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] 31-31: 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)
[Warning] 33-33: Initializing an optional variable with nil is redundant
(redundant_optional_initialization)
[Warning] 34-34: Initializing an optional variable with nil is redundant
(redundant_optional_initialization)
Projects/DesignSystem/DesignCore/Sources/JobSelection/JobOccupation.swift (1)
100-100
: requestValue 구현이 단순화되었습니다.이전의 switch 문을 제거하고 rawValue를 직접 반환하도록 개선한 것이 좋은 변경사항입니다. 코드가 더 간결해지고 유지보수가 쉬워졌습니다.
하나 제안드리고 싶은 점은, requestValue 프로퍼티가 단순히 rawValue를 반환하는 역할만 한다면 이 프로퍼티를 제거하고 직접 rawValue를 사용하는 것도 고려해 보시면 좋을 것 같습니다.
-public var requestValue: String { - return self.rawValue -}Projects/Features/Home/Sources/HomeMain/HomeMainView.swift (1)
38-61
: 탭 인터페이스 개선사항 제안현재 구현은 잘 작동하지만, 다음과 같은 개선사항을 고려해보시기 바랍니다:
- 하드코딩된 spacing 값을 DesignSystem 상수로 분리
- 불투명도 값(0.2)을 DesignSystem에서 관리
- 접근성 지원을 위한 VoiceOver 레이블 추가
다음과 같이 수정을 제안드립니다:
- HStack(spacing: 30) { + HStack(spacing: DesignCore.Spacing.large) { // ... - .foregroundColor(isSelected ? DesignCore.Colors.grey500 : DesignCore.Colors.grey500.opacity(0.2)) + .foregroundColor(isSelected ? DesignCore.Colors.grey500 : DesignCore.Colors.grey500Dimmed) // ... + .accessibilityLabel("\(tab.title) 탭")Projects/Model/Model/Sources/Auth/Domain/UserInfo.swift (2)
40-49
: Mock 데이터의 현실성 개선 필요하드코딩된 값들이 실제 사용 사례를 잘 대표하지 못할 수 있습니다. 전화번호와 같은 데이터는 다양한 패턴을 테스트할 수 있도록 여러 mock 케이스를 제공하는 것이 좋습니다.
다음과 같이 여러 mock 케이스를 추가하는 것을 고려해보세요:
public static var mock: UserInfo { .init( id: UUID().uuidString, name: "김지수", phone: "01012341234", profile: .mock, dreamPartner: .mock ) } +public static var mockWithInternationalPhone: UserInfo { + .init( + id: UUID().uuidString, + name: "John Doe", + phone: "+821012341234", + profile: .mock, + dreamPartner: .mock + ) +}
80-89
: UserInfoProfile mock 데이터의 다양성 부족현재 구현된 mock 데이터는 매우 특정한 케이스(1980년생, 남성)만을 다루고 있습니다. 다양한 연령대와 성별을 테스트하기 위해서는 추가적인 mock 케이스가 필요할 수 있습니다.
다음과 같이 다양한 프로필 mock을 추가하는 것을 고려해보세요:
public static var mock: UserInfoProfile { .init( gender: .male, birthYear: 1980, companyId: nil, jobOccupation: "IT_INFORMATION", locations: ["용인", "성남", "강남구", "중구"] ) } +public static var mockYounger: UserInfoProfile { + .init( + gender: .female, + birthYear: 1995, + companyId: "company_123", + jobOccupation: "DESIGN", + locations: ["서울", "강남구"] + ) +}Projects/DesignSystem/DesignCore/Sources/TagListView/TagListCollectionView.swift (3)
124-128
: MARK 주석 형식을 수정해주세요.Swift 스타일 가이드에 따라 MARK 주석은 다음과 같은 형식을 따라야 합니다:
- //MARK: - Constants + // MARK: - Constants🧰 Tools
🪛 SwiftLint
[Warning] 124-124: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 124-124: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
131-155
: 성능 최적화 및 문서화 개선이 필요합니다.
- 성능 최적화:
- 현재 각 태그마다 새로운 UILabel을 생성하고 있어 성능에 영향을 줄 수 있습니다.
- 레이블 생성을 최소화하기 위해 NSAttributedString의 boundingRect를 사용하는 것을 고려해보세요.
- 문서화:
- 복잡한 계산 로직이므로 메서드에 대한 문서화 주석(documentation comments)을 추가하면 좋을 것 같습니다.
다음과 같이 개선해보세요:
+ /// 태그 목록의 전체 높이를 계산합니다. + /// - Parameters: + /// - tags: 표시할 태그 모델 배열 + /// - deviceWidth: 디바이스의 너비 + /// - Returns: 태그들을 표시하는데 필요한 전체 높이 public static func calculateHeight(tags: [TagModel], deviceWidth: CGFloat) -> CGFloat { var currentLineWidth: CGFloat = 0 var totalHeight: CGFloat = verticalInsets var currentLineCount: Int = 1 + + let attributes: [NSAttributedString.Key: Any] = [ + .font: UIFont.pretendard(._500, size: 14) + ] for tag in tags { - let label = UILabel() - label.font = UIFont.pretendard(._500, size: 14) - label.text = tag.name - label.sizeToFit() + let size = (tag.name as NSString).boundingRect( + with: CGSize(width: .greatestFiniteMagnitude, height: 40), + options: .usesLineFragmentOrigin, + attributes: attributes, + context: nil + ) - let cellWidth = label.frame.size.width + 24 + let cellWidth = ceil(size.width) + 24
130-130
: MARK 주석 형식을 수정해주세요.Swift 스타일 가이드에 따라 MARK 주석은 다음과 같은 형식을 따라야 합니다:
- //MARK: - 동적 높이 계산 + // MARK: - 동적 높이 계산🧰 Tools
🪛 SwiftLint
[Warning] 130-130: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 130-130: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
Projects/Features/Home/Sources/ProfilePannel/ProfilePannelView.swift (3)
41-48
: circleDot 뷰의 색상값 추상화 필요하드코딩된 색상값들을 DesignCore로 이동하여 재사용성과 일관성을 높일 필요가 있습니다.
- .stroke(Color(hex: 0xD2D2D2), lineWidth: 1) - .fill(Color(hex: 0xEBEBEB)) + .stroke(DesignCore.Colors.borderGray, lineWidth: 1) + .fill(DesignCore.Colors.backgroundGray)
209-216
: 프리뷰 케이스 추가 필요현재는 기본적인 케이스만 프리뷰로 제공되고 있습니다. 다양한 상황에서의 UI를 확인할 수 있도록 추가 프리뷰 케이스가 필요합니다.
다음과 같은 프리뷰 케이스 추가를 제안드립니다:
#Preview("긴 텍스트") { NavigationView { ProfilePannelView( name: "매우 긴 이름을 가진 사용자", profile: .mockWithLongText ) } } #Preview("데이터 없음") { NavigationView { ProfilePannelView( name: "", profile: .mockEmpty ) } }
16-207
: 아키텍처 개선 제안현재 구현은 MVI 패턴을 따르고 있지만, 몇 가지 개선이 필요한 부분이 있습니다:
- 상태 관리: 현재 일부 데이터(태그 등)가 뷰에 직접 하드코딩되어 있어 상태 관리가 완벽하지 않습니다.
- 재사용성: 색상값과 스타일링 코드가 반복되어 있어 유지보수가 어려울 수 있습니다.
- 에러 처리: 데이터 로딩 실패나 잘못된 입력에 대한 처리가 없습니다.
다음과 같은 개선을 제안드립니다:
- ProfilePannelModel에 모든 데이터 상태를 포함
- 스타일링 관련 코드를 DesignCore로 이동
- 에러 상태 추가 및 처리
Projects/Features/Home/Sources/Profile/ProfileView.swift (3)
74-96
: 'ZStack' 내 'RoundedRectangle' 구조 개선 제안두 개의 'RoundedRectangle'을 사용하여 배경과 테두리를 구현하고 있는데, 이를 하나의 뷰로 통합하여 코드의 간결성과 성능을 향상시킬 수 있습니다.
다음과 같이 수정할 수 있습니다:
- ZStack { - RoundedRectangle(cornerRadius: 24) - .fill(.white) - - RoundedRectangle(cornerRadius: 10) - .fill(DesignCore.Colors.grey50) - .strokeBorder( - style: StrokeStyle( - lineWidth: 3, - dash: [8, 8] - ) - ) - .foregroundStyle(Color(hex: 0xE0DEDD)) - .padding(.all, 8) - - // 기타 내용 - } + RoundedRectangle(cornerRadius: 24) + .fill(.white) + .overlay( + RoundedRectangle(cornerRadius: 10) + .stroke( + Color(hex: 0xE0DEDD), + style: StrokeStyle( + lineWidth: 3, + dash: [8, 8] + ) + ) + .background(DesignCore.Colors.grey50) + .cornerRadius(10) + .padding(8) + ) + // 기타 내용
108-110
: 'task'와 'onAppear'의 중복 사용 확인 필요현재 '.task'에서 'intent.task()'를, '.onAppear'에서 'intent.onAppear()'를 호출하고 있습니다. 두 메서드가 비슷한 역할을 수행한다면 하나로 통합하여 코드의 복잡성을 줄일 수 있습니다.
124-127
: 'NavigationView'를 'NavigationStack'으로 변경 권장iOS 16부터 'NavigationView'는 폐기 예정이며, 대신 'NavigationStack'을 사용하는 것이 권장됩니다. 최신 iOS 버전에 맞추어 업데이트하는 것을 추천드립니다.
다음과 같이 수정할 수 있습니다:
- NavigationView { + NavigationStack { HomeMainView(userInfo: .mock) }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (9)
Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/Profile/building_fill.imageset/building_fill.png
is excluded by!**/*.png
Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/Profile/building_fill.imageset/[email protected]
is excluded by!**/*.png
Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/Profile/building_fill.imageset/[email protected]
is excluded by!**/*.png
Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/Profile/business_fill.imageset/business_fill.png
is excluded by!**/*.png
Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/Profile/business_fill.imageset/[email protected]
is excluded by!**/*.png
Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/Profile/business_fill.imageset/[email protected]
is excluded by!**/*.png
Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/Profile/location_fill.imageset/location_fill.png
is excluded by!**/*.png
Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/Profile/location_fill.imageset/[email protected]
is excluded by!**/*.png
Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/Profile/location_fill.imageset/[email protected]
is excluded by!**/*.png
📒 Files selected for processing (23)
Projects/App/Sources/Navigation/NavigationStack.swift
(1 hunks)Projects/App/Sources/Splash/SplashAnimatedView.swift
(2 hunks)Projects/Core/CommonKit/Sources/Path/PathTypes.swift
(1 hunks)Projects/Core/CoreKit/Sources/Int+Ext.swift
(1 hunks)Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/Profile/Contents.json
(1 hunks)Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/Profile/building_fill.imageset/Contents.json
(1 hunks)Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/Profile/business_fill.imageset/Contents.json
(1 hunks)Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/Profile/location_fill.imageset/Contents.json
(1 hunks)Projects/DesignSystem/DesignCore/Sources/JobSelection/JobOccupation.swift
(2 hunks)Projects/DesignSystem/DesignCore/Sources/TagListView/TagListCollectionView.swift
(1 hunks)Projects/Features/Home/Sources/HomeMain/HomeMainIntent.swift
(3 hunks)Projects/Features/Home/Sources/HomeMain/HomeMainModel.swift
(4 hunks)Projects/Features/Home/Sources/HomeMain/HomeMainView.swift
(4 hunks)Projects/Features/Home/Sources/Profile/ProfileIntent.swift
(1 hunks)Projects/Features/Home/Sources/Profile/ProfileModel.swift
(1 hunks)Projects/Features/Home/Sources/Profile/ProfileView.swift
(1 hunks)Projects/Features/Home/Sources/ProfilePannel/ProfilePannelIntent.swift
(1 hunks)Projects/Features/Home/Sources/ProfilePannel/ProfilePannelModel.swift
(1 hunks)Projects/Features/Home/Sources/ProfilePannel/ProfilePannelView.swift
(1 hunks)Projects/Features/SignUp/Sources/AuthSignUp/AuthPhoneVerify/AuthPhoneVerifyIntent.swift
(1 hunks)Projects/Features/SignUp/Sources/DreamPartnerInput/DreamPartnerDistance/DreamPartnerDistanceIntent.swift
(2 hunks)Projects/Features/SignUp/UnitTest/AuthPhoneVerifyTest.swift
(1 hunks)Projects/Model/Model/Sources/Auth/Domain/UserInfo.swift
(3 hunks)
✅ Files skipped from review due to trivial changes (4)
- Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/Profile/Contents.json
- Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/Profile/building_fill.imageset/Contents.json
- Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/Profile/business_fill.imageset/Contents.json
- Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/Profile/location_fill.imageset/Contents.json
🧰 Additional context used
📓 Learnings (1)
Projects/Core/CommonKit/Sources/Path/PathTypes.swift (1)
Learnt from: jisu15-kim
PR: Student-Center/3days-ios#28
File: Projects/Core/CommonKit/Sources/Path/PathTypes.swift:58-75
Timestamp: 2024-10-09T02:55:39.541Z
Learning: 'Projects/Core/CommonKit/Sources/Path/PathTypes.swift' 파일의 네비게이션 경로를 나타내는 'PathType'과 'SignUpSubViewType' enum에서는 연관값과 관계없이 동일한 케이스는 동일한 뷰로 간주해야 합니다. 따라서 Hashable 구현 시 연관값을 무시하고 동일한 케이스를 동일하게 취급합니다.
🪛 SwiftLint
Projects/DesignSystem/DesignCore/Sources/TagListView/TagListCollectionView.swift
[Warning] 124-124: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 130-130: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 124-124: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 130-130: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
Projects/Features/Home/Sources/HomeMain/HomeMainIntent.swift
[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/Home/Sources/HomeMain/HomeMainModel.swift
[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)
Projects/Features/Home/Sources/Profile/ProfileIntent.swift
[Warning] 14-14: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 29-29: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 45-45: 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] 29-29: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 45-45: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
Projects/Features/Home/Sources/Profile/ProfileModel.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] 45-45: 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] 45-45: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
Projects/Features/Home/Sources/ProfilePannel/ProfilePannelIntent.swift
[Warning] 14-14: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 29-29: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 46-46: 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] 29-29: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
[Warning] 46-46: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
Projects/Features/Home/Sources/ProfilePannel/ProfilePannelModel.swift
[Warning] 16-16: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 31-31: 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] 31-31: 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)
[Warning] 33-33: Initializing an optional variable with nil is redundant
(redundant_optional_initialization)
[Warning] 34-34: Initializing an optional variable with nil is redundant
(redundant_optional_initialization)
🔇 Additional comments (18)
Projects/Features/Home/Sources/Profile/ProfileIntent.swift (1)
45-56
: 미구현된 메서드 확인이 필요합니다
onTapNextButton()
과 task()
메서드가 비어있습니다. 이것이 의도적인 것인지 확인이 필요합니다.
향후 구현이 필요한 경우, TODO 주석을 추가하거나 구현을 완료하는 것이 좋겠습니다. 구현에 도움이 필요하시다면 말씀해 주세요.
🧰 Tools
🪛 SwiftLint
[Warning] 45-45: Prefer at least one space after slashes for comments
(comment_spacing)
[Warning] 45-45: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
Projects/Features/Home/Sources/ProfilePannel/ProfilePannelIntent.swift (1)
54-57
: 비어있는 메서드 구현에 대한 설명이 필요합니다
task()
와 onTapNextButton()
메서드가 비어있습니다. 향후 구현 예정이라면 TODO 주석을 추가하거나, 의도적으로 비워둔 것이라면 그 이유를 문서화해주세요.
구현이 필요한 경우 도움이 필요하시다면 말씀해 주세요.
Projects/Features/Home/Sources/HomeMain/HomeMainIntent.swift (3)
12-13
: Model과 NetworkKit 임포트 추가 확인됨
필요한 모듈들이 적절하게 추가되었습니다.
19-19
: AuthService 의존성 주입 구현이 잘 되었습니다
기본값으로 싱글톤을 사용하면서도 테스트를 위한 의존성 주입이 가능하도록 구현되어 있습니다. 단위 테스트 작성이 용이할 것으로 보입니다.
Also applies to: 24-29
45-47
: DataModel에 UserInfo 추가 확인
PR의 목적에 맞게 프로필 기능을 위한 UserInfo가 추가되었습니다. Optional 타입을 사용한 것이 적절해 보입니다.
Projects/App/Sources/Navigation/NavigationStack.swift (1)
31-32
: HomeMainView 구현 확인이 필요합니다.
userInfo
파라미터가 HomeMainView
에서 올바르게 처리되는지 확인이 필요합니다.
다음 스크립트로 HomeMainView
구현을 확인해보겠습니다:
✅ Verification successful
userInfo
파라미터가 적절하게 처리되고 있습니다.
HomeMainView
는 userInfo
파라미터를 다음과 같이 올바르게 처리하고 있습니다:
init(userInfo:)
메서드에서 파라미터를HomeMainIntent
의 입력으로 전달HomeMainModel
에서userInfo
상태를 관리HomeMainIntent
에서userInfo
값을 검증하고 모델에 설정- 뷰에서
userInfo
상태에 따라 적절한 UI 렌더링 (프로필 탭 등)
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# HomeMainView가 userInfo 파라미터를 올바르게 처리하는지 확인
# HomeMainView 정의 검색
ast-grep --pattern 'struct HomeMainView {
$$$
}'
# userInfo 사용 패턴 검색
rg -A 5 'userInfo' 'Projects/App/Sources/Home'
Length of output: 163
Script:
#!/bin/bash
# HomeMainView 파일 위치 찾기
fd HomeMainView
# HomeMainView 정의와 userInfo 사용 검색
rg -g '*.swift' -A 5 'HomeMainView'
# userInfo 사용 패턴 전체 검색
rg -g '*.swift' -A 5 'userInfo'
Length of output: 25529
Projects/Features/Home/Sources/HomeMain/HomeMainModel.swift (2)
19-19
: 프로토콜에 사용자 정보 상태 추가가 적절해 보입니다.
상태 프로토콜에 옵셔널 UserInfo 프로퍼티를 추가한 것이 적절합니다. 읽기 전용으로 선언하여 상태 관리의 단방향 흐름을 잘 유지하고 있습니다.
33-34
: 기본 탭 변경이 의도된 것인지 확인이 필요합니다.
selectedTab의 기본값이 .home
에서 .profile
로 변경되었습니다. 이는 앱의 초기 상태에 영향을 미칠 수 있습니다.
Projects/Features/Home/Sources/Profile/ProfileModel.swift (1)
14-85
: 전반적으로 잘 구현된 MVVM 아키텍처입니다.
상태 관리와 에러 처리가 잘 분리되어 있고, 프로토콜을 통한 인터페이스 정의가 명확합니다. 다만 몇 가지 개선사항을 제안드립니다:
- 상태 변경 시 적절한 로깅 추가
- 입력값 검증 로직 강화
- 문서화 보완
🧰 Tools
🪛 SwiftLint
[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] 45-45: 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] 45-45: MARK comment should be in valid format. e.g. '// MARK: ...' or '// MARK: - ...'
(mark)
Projects/Features/SignUp/Sources/DreamPartnerInput/DreamPartnerDistance/DreamPartnerDistanceIntent.swift (1)
91-91
: 네비게이션 흐름 변경 승인
홈 화면으로의 네비게이션 변경과 사용자 정보 전달이 적절하게 구현되었습니다. PR의 목적인 프로필 탭 구현과 일관성 있게 작성되었습니다.
Projects/DesignSystem/DesignCore/Sources/JobSelection/JobOccupation.swift (1)
11-47
: 직업 카테고리 열거형의 표준화된 문자열 값 적용이 잘 되었습니다.
열거형에 String 원시값을 추가하고 각 케이스에 표준화된 영문 식별자를 부여한 것이 API 통신 시 일관성을 유지하는데 도움이 될 것 같습니다. 각 직업군의 한글 설명도 주석으로 잘 작성되어 있습니다.
Projects/Features/Home/Sources/HomeMain/HomeMainView.swift (3)
13-13
: 초기화 로직이 잘 구현되었습니다!
UserInfo를 MVI 컨테이너에 올바르게 통합하여 사용자 정보를 효과적으로 관리하고 있습니다.
Also applies to: 22-33
62-74
: 첫 번째 탭 콘텐츠 구현 필요
첫 번째 탭에 임시 텍스트가 있습니다. 이는 추후 구현이 필요해 보입니다.
홈 탭 구현이 필요한 상황입니다. 구현 계획이 있으시다면 공유해 주시고, 도움이 필요하시다면 제안드리도록 하겠습니다.
85-85
: 네비게이션 설정과 프리뷰가 적절히 구현되었습니다!
네비게이션 설정과 목업 데이터를 활용한 프리뷰가 SwiftUI 모범 사례를 잘 따르고 있습니다.
Also applies to: 92-92
Projects/Core/CommonKit/Sources/Path/PathTypes.swift (1)
27-27
: 홈 케이스 수정이 적절합니다
UserInfo?
타입의 선택적 매개변수를 추가한 것은 다음과 같은 이유로 적절합니다:
- 프로필 탭 구현을 위한 사용자 정보 전달이 가능해집니다
- Optional 타입을 사용하여 유연성을 확보했습니다
Projects/Features/SignUp/Sources/AuthSignUp/AuthPhoneVerify/AuthPhoneVerifyIntent.swift (2)
134-134
: 기존 사용자 네비게이션 처리가 적절히 구현되었습니다.
사용자 정보를 홈 화면으로 전달하는 방식이 잘 구현되어 있습니다. AppCoordinator.shared.userInfo
를 통해 전역 사용자 정보를 활용하는 것이 적절합니다.
140-144
: 네비게이션 로직이 적절히 구현되었습니다.
홈 화면으로의 네비게이션을 changeRootView
로 처리하고, 다른 화면은 push
로 처리하는 구분이 잘 되어있습니다. 다만, 홈 화면 진입 시 사용자 정보가 올바르게 설정되어 있는지 확인이 필요할 수 있습니다.
✅ Verification successful
홈 화면 진입 시 사용자 정보가 적절히 설정되고 있습니다.
코드 분석 결과, 다음과 같은 안전장치들이 확인되었습니다:
AppCoordinator
에서 토큰 검증 및 사용자 정보 설정이 이루어집니다- 홈 화면 진입 시
HomeMainIntent
에서 사용자 정보가 없는 경우 자동으로 서버에서 정보를 가져옵니다 - 기존 사용자의 경우
AppCoordinator.shared.userInfo
를 통해 정보가 전달됩니다
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# AppCoordinator에서 userInfo 설정 로직 확인
ast-grep --pattern 'class AppCoordinator {
$$$
func validateToken($$$) {
$$$
}
$$$
}'
Length of output: 99
Script:
#!/bin/bash
# AppCoordinator 클래스의 구현 확인
rg -A 5 "class AppCoordinator"
# 홈 화면 진입 전 사용자 정보 설정 관련 메서드 검색
rg -A 5 "changeRootView|userInfo|validateUser"
# AuthPhoneVerifyIntent 클래스에서 사용자 정보 설정 관련 코드 확인
rg -A 10 "class AuthPhoneVerifyIntent"
Length of output: 28003
Projects/Features/Home/Sources/ProfilePannel/ProfilePannelView.swift (1)
9-14
: LGTM! 필요한 모듈들이 잘 임포트되어 있습니다.
모든 필수 모듈들이 적절하게 임포트되어 있으며, 불필요한 임포트는 없습니다.
func onAppear() { | ||
Task { | ||
if let userInfo = input.userInfo { | ||
model?.setUserInfo(userInfo: userInfo) | ||
} else { | ||
let userInfo = try await authService.requestMyUserInfo() | ||
AppCoordinator.shared.userInfo = userInfo | ||
model?.setUserInfo(userInfo: userInfo) | ||
} | ||
} | ||
} |
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 onAppear() {
Task {
+ model?.setLoading(true)
if let userInfo = input.userInfo {
model?.setUserInfo(userInfo: userInfo)
} else {
+ do {
let userInfo = try await authService.requestMyUserInfo()
AppCoordinator.shared.userInfo = userInfo
model?.setUserInfo(userInfo: userInfo)
+ } catch {
+ model?.setError(error)
+ }
}
+ model?.setLoading(false)
}
}
Committable suggestion skipped: line range outside the PR's diff.
if let userInfo = AppCoordinator.shared.userInfo { | ||
AppCoordinator.shared.changeRootView(.home(userInfo)) | ||
} |
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.
userInfo가 nil일 경우의 처리 로직 필요
현재 구현은 userInfo가 nil일 경우 아무런 동작도 하지 않습니다. 이는 잠재적인 데드락이나 사용자 경험 저하를 초래할 수 있습니다.
다음과 같이 수정하는 것을 제안합니다:
@MainActor
private func pushToHomeView() {
if let userInfo = AppCoordinator.shared.userInfo {
AppCoordinator.shared.changeRootView(.home(userInfo))
+ } else {
+ Logger.error("유저 정보 없음")
+ AppCoordinator.shared.changeRootView(.signUp(.authPhoneInput))
}
}
📝 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.
if let userInfo = AppCoordinator.shared.userInfo { | |
AppCoordinator.shared.changeRootView(.home(userInfo)) | |
} | |
if let userInfo = AppCoordinator.shared.userInfo { | |
AppCoordinator.shared.changeRootView(.home(userInfo)) | |
} else { | |
Logger.error("유저 정보 없음") | |
AppCoordinator.shared.changeRootView(.signUp(.authPhoneInput)) | |
} |
@@ -146,7 +146,7 @@ | |||
/// 로그아웃 -> 애니메이션 계속진행 | |||
if isAuthorized { | |||
try? await Task.sleep(for: .seconds(1)) | |||
pushToHomeView() | |||
await pushToHomeView() |
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
await 키워드 사용에 대한 에러 처리 개선 필요
try?
를 사용하여 에러를 무시하는 대신, 적절한 에러 처리를 구현하는 것이 좋습니다. 스플래시 화면에서의 네비게이션 실패는 사용자 경험에 중요한 영향을 미칠 수 있습니다.
다음과 같이 수정하는 것을 제안합니다:
- await pushToHomeView()
+ do {
+ await pushToHomeView()
+ } catch {
+ Logger.error("홈 화면 이동 실패: \(error)")
+ // 적절한 폴백 처리 또는 사용자에게 알림
+ }
Committable suggestion skipped: line range outside the PR's diff.
Capsule() | ||
.inset(by: 1) | ||
.stroke(DesignCore.Colors.blue300, lineWidth: 1) | ||
.fill(Color(hex: 0xF2F9FF)) |
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.
'Capsule'의 'stroke'와 'fill' 순서 수정 필요
'Capsule'에 'stroke'를 적용한 후 'fill'을 사용하면 'stroke'가 덮여 원하는 효과가 나타나지 않을 수 있습니다. 'fill'을 먼저 적용하고 그 위에 'stroke'를 오버레이하는 것이 좋습니다.
다음과 같이 수정할 수 있습니다:
- Capsule()
- .inset(by: 1)
- .stroke(DesignCore.Colors.blue300, lineWidth: 1)
- .fill(Color(hex: 0xF2F9FF))
+ Capsule()
+ .fill(Color(hex: 0xF2F9FF))
+ .overlay(
+ Capsule()
+ .inset(by: 1)
+ .stroke(DesignCore.Colors.blue300, lineWidth: 1)
+ )
📝 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.
Capsule() | |
.inset(by: 1) | |
.stroke(DesignCore.Colors.blue300, lineWidth: 1) | |
.fill(Color(hex: 0xF2F9FF)) | |
Capsule() | |
.fill(Color(hex: 0xF2F9FF)) | |
.overlay( | |
Capsule() | |
.inset(by: 1) | |
.stroke(DesignCore.Colors.blue300, lineWidth: 1) | |
) |
구현사항
앞으로 개선 사항(선택)
스크린샷(선택)
Summary by CodeRabbit
릴리스 노트
신규 기능
ProfileView
및ProfilePannelView
가 추가되었습니다.버그 수정
문서화
테스트