-
Notifications
You must be signed in to change notification settings - Fork 0
[FIX] 로그인 툴팁이 중복을 발생하던 문제 수정 #164
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
Conversation
- 모든 env 파일 무시 규칙 추가
- DIContainer 의존성 추가 - 프로젝트에 필요한 의존성 추가 - Factory를 이용한 화면 전환으로 변경
- 화면 전환에 필요한 화면을 별도의 Mock 객체로 대체
- 애플 로그인으로 회원가입 시도 → 뒤로가기 → 카카오 로그인 시도 → 회원가입시 애플의 인가코드가 들어가는 문제 발생 가능
- 요구사항 분석과정에서 코멘트의 변경이 main/sub 만으로 나뉘지 않을것으로 예측함 - 기존에 isSubLogin이라는 bool로 분기를 하던것도 LoginSceneType을 별도로 선언하여 타입 추가에 대한 대비
…recent-login-duplication # Conflicts: # Poppool/PresentationLayer/SearchFeature/SearchFeature.xcodeproj/project.pbxproj
|
""" Walkthrough이번 변경은 로그인 및 회원가입 관련 기능을 모듈화하여 LoginFeature와 PresentationTesting 프레임워크를 도입하고, 각종 팩토리 패턴 기반의 의존성 주입을 Presentation 레이어에 적용하는 대규모 구조 리팩토링입니다. 기존 로그인 화면 및 리액터 구현이 삭제되고, 새로운 모듈/팩토리/테스트 코드와 자원 파일이 추가되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant AppDelegate
participant DIContainer
participant LoginFactory
participant LoginViewController
participant LoginReactor
User->>AppDelegate: 앱 실행
AppDelegate->>DIContainer: 팩토리/서비스 등록
AppDelegate->>LoginFactory: make(.main, text)
LoginFactory->>LoginViewController: 생성 및 반환
LoginViewController->>LoginReactor: 리액터 바인딩
User->>LoginViewController: 로그인 버튼 클릭
LoginViewController->>LoginReactor: Action 전달
LoginReactor->>LoginReactor: 로그인 로직/토큰 저장
LoginReactor-->>LoginViewController: Mutation(화면 전환)
LoginViewController->>DIContainer: 팩토리로 다음 화면 생성
Estimated code review effort4 (60–120분) Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: .coderabbit.yaml 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (3)
✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
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: 11
🧹 Nitpick comments (14)
Poppool/PresentationLayer/Presentation/Presentation/Scene/SignUp/Main/SignUpMainReactor.swift (1)
138-141: lastLogin 추적 로직이 PR 목표에 부합합니다.회원가입 성공 후 마지막 로그인 방식을 저장하는 로직이 추가되어 로그인 툴팁 중복 문제 해결에 도움이 됩니다. authorizationCode 존재 여부로 Apple/Kakao 로그인을 구분하는 방식이 적절합니다.
하드코딩된 문자열 대신 상수를 사용하는 것을 고려해보세요:
private enum LoginType { static let apple = "apple" static let kakao = "kakao" } // 사용 시: self.userDefaultService.save( keyType: .lastLogin, value: authrizationCode != nil ? LoginType.apple : LoginType.kakao )Poppool/PresentationLayer/Presentation/PresentationInterface/Factory/WaveTabbarFactory.swift (2)
3-5:Tabbar→TabBar로 용어 통일 권장UIKit 클래스명(UITabBarController)과 달리
WaveTabbarFactory는 소문자 b 를 사용하고 있습니다. 프로젝트 전반에TabBar/Tabbar가 혼재되면 오타나 DI 등록 실패를 유발할 수 있으므로, 초기에 용어를 맞춰두는 편이 안전합니다.-public protocol WaveTabbarFactory { +public protocol WaveTabBarFactory {
3-5: UI 객체 생성 메서드에@MainActor추가 고려
make()가 UIKit 객체를 반환하므로 메인 스레드에서 호출됨을 명시하면, 비동기 컨텍스트에서 컴파일 타임에 스레드 안전성을 확보할 수 있습니다.-public protocol WaveTabbarFactory { - func make() -> UITabBarController +public protocol WaveTabbarFactory { + @MainActor + func make() -> UITabBarController }Poppool/PresentationLayer/Presentation/PresentationInterface/Factory/FAQFactory.swift (1)
3-5: FAQFactory에도@MainActor부여 추천앞선 TabBar와 동일한 맥락으로 UI 생성 메서드임을 명확히 할 수 있습니다.
Poppool/CoreLayer/Infrastructure/Infrastructure/Service/KeyChainService.swift (1)
83-87: 로그 메시지 오타 –fetched대신saved성공 로그에 “fetched”가 들어가 있어 의미가 어색합니다.
- "Successfully fetched \(type.rawValue) from KeyChain: \(value)", + "Successfully saved \(type.rawValue) to KeyChain: \(value)",Poppool/PresentationLayer/Presentation/Presentation/Scene/Splash/SplashController.swift (1)
61-62: 키체인 저장 작업의 오류 처리를 개선하는 것을 고려해보세요.키체인 저장 작업의 결과를 무시하고 있습니다. 실패 시 로깅이나 오류 처리를 추가하는 것이 좋겠습니다.
- _ = owner.keyChainService.saveToken(type: .accessToken, value: newAccessToken) - _ = owner.keyChainService.saveToken(type: .refreshToken, value: newRefreshToken) + if case .failure(let error) = owner.keyChainService.saveToken(type: .accessToken, value: newAccessToken) { + Logger.log("Failed to save access token: \(error)", category: .error) + } + if case .failure(let error) = owner.keyChainService.saveToken(type: .refreshToken, value: newRefreshToken) { + Logger.log("Failed to save refresh token: \(error)", category: .error) + }Poppool/PresentationLayer/Presentation/Presentation/Scene/Detail/DetailReactor.swift (3)
171-177: 팩토리 패턴 사용이 우수하지만 중복 코드 개선 권장LoginFactory를 통한 로그인 뷰 컨트롤러 생성이 잘 구현되었습니다. 하지만 동일한 텍스트가 여러 곳에서 반복되고 있습니다.
다음과 같이 상수로 추출하는 것을 고려해보세요:
+private enum LoginText { + static let commentPrompt = "간편하게 SNS 로그인하고\n다른 코멘트를 확인해볼까요?" +} -rootViewController: factory.make(.sub, text: "간편하게 SNS 로그인하고\n다른 코멘트를 확인해볼까요?") +rootViewController: factory.make(.sub, text: LoginText.commentPrompt)
208-214: 동일한 리팩토링 권장사항 적용여기서도 동일한 텍스트 상수화를 적용하세요.
244-250: 동일한 리팩토링 권장사항 적용여기서도 동일한 텍스트 상수화를 적용하세요.
Poppool/PresentationLayer/LoginFeature/LoginFeature/Login/LoginView.swift (2)
62-64: 프로덕션 코드에서 디버그 출력 제거 필요deinit의 디버그 print 문은 프로덕션 코드에서 제거해야 합니다.
-deinit { - print("DEINIT DEBUG: \(#file)") -} +deinit { }
84-137: 제약 조건 설정 메서드 분리 권장setupConstraints 메서드가 길어서 가독성이 떨어집니다. 논리적 그룹별로 분리하는 것을 고려해보세요.
func setupConstraints() { + setupHeaderConstraints() + setupLogoAndTitleConstraints() + setupButtonConstraints() + setupFooterConstraints() +} + +private func setupHeaderConstraints() { guestButton.snp.makeConstraints { make in make.top.equalTo(safeAreaLayoutGuide).inset(11) make.trailing.equalToSuperview().inset(20) } xmarkButton.snp.makeConstraints { make in make.top.equalTo(safeAreaLayoutGuide).inset(11) make.trailing.equalToSuperview().inset(20) make.size.equalTo(32) } +}Poppool/PresentationLayer/LoginFeature/LoginFeature/Login/LoginViewController.swift (2)
12-25: 설계 관련 주석을 문서화하거나 제거하세요현재 코드에 있는 설계 관련 주석들은 구현 세부사항을 설명하고 있습니다. 이러한 내용은 별도의 문서로 관리하거나, 실제 구현에 필요한 부분만 간결하게 남기는 것이 좋습니다.
117-118: @dependency 속성 래퍼의 위치를 재고려하세요팩토리 인스턴스들이 switch 문 내부에서 생성되고 있습니다. 이는 매번 새로운 인스턴스를 생성하므로 성능에 영향을 줄 수 있습니다.
클래스 레벨에서 팩토리들을 선언하는 것을 고려해보세요:
+@Dependency private var signUpFactory: SignUpFactory +@Dependency private var waveTabbarFactory: WaveTabbarFactory +@Dependency private var faqFactory: FAQFactory private func bindOutput(reactor: Reactor) { reactor.pulse(\.$present) .skip(1) .withUnretained(self) .subscribe { (owner, target) in guard let target = target else { return } switch target { case .signUp(let isFirstResponder, let authrizationCode): - @Dependency var factory: SignUpFactory owner.navigationController?.pushViewController( - factory.make( + owner.signUpFactory.make( isFirstResponder: isFirstResponder, authrizationCode: authrizationCode ), animated: true )Also applies to: 127-128, 134-135
Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/App/AppDelegate.swift (1)
57-59: Mock 팩토리 사용에 대한 문서화가 필요합니다데모 앱에서 SignUp, WaveTabbar, FAQ 팩토리에 Mock 구현체를 사용하고 있습니다. 이에 대한 이유를 주석으로 설명하면 좋겠습니다.
private func registerFactory() { DIContainer.register(LoginFactory.self) { return LoginFactoryImpl() } + // 데모 앱에서는 실제 구현 대신 Mock을 사용합니다 DIContainer.register(SignUpFactory.self) { return SignUpFactoryMock() } DIContainer.register(WaveTabbarFactory.self) { return WaveTabbarFactoryMock() } DIContainer.register(FAQFactory.self) { return FAQFactoryMock() } }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/Resource/Assets.xcassets/icon_login_apple.imageset/logo.svgis excluded by!**/*.svgPoppool/PresentationLayer/LoginFeature/LoginFeatureDemo/Resource/Assets.xcassets/icon_login_kakao.imageset/logo.svgis excluded by!**/*.svgPoppool/PresentationLayer/LoginFeature/LoginFeatureDemo/Resource/Assets.xcassets/image_login_logo.imageset/logo.svgis excluded by!**/*.svg
📒 Files selected for processing (47)
Poppool/CoreLayer/Infrastructure/Infrastructure/Service/KeyChainService.swift(2 hunks)Poppool/CoreLayer/Infrastructure/Infrastructure/Service/UserDefaultService.swift(1 hunks)Poppool/Poppool.xcodeproj/project.pbxproj(7 hunks)Poppool/Poppool.xcworkspace/contents.xcworkspacedata(1 hunks)Poppool/Poppool.xcworkspace/xcshareddata/swiftpm/Package.resolved(3 hunks)Poppool/Poppool/Application/AppDelegate.swift(2 hunks)Poppool/PresentationLayer/DesignSystem/DesignSystem/Components/PPLabel.swift(1 hunks)Poppool/PresentationLayer/LoginFeature/LoginFeature.xcodeproj/project.pbxproj(1 hunks)Poppool/PresentationLayer/LoginFeature/LoginFeature.xcodeproj/xcshareddata/xcschemes/LoginFeatureDemo.xcscheme(1 hunks)Poppool/PresentationLayer/LoginFeature/LoginFeature/Factory/LoginFactory.swift(1 hunks)Poppool/PresentationLayer/LoginFeature/LoginFeature/Login/LastLoginView.swift(1 hunks)Poppool/PresentationLayer/LoginFeature/LoginFeature/Login/LoginReactor.swift(1 hunks)Poppool/PresentationLayer/LoginFeature/LoginFeature/Login/LoginView.swift(1 hunks)Poppool/PresentationLayer/LoginFeature/LoginFeature/Login/LoginViewController.swift(1 hunks)Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/App/AppDelegate.swift(1 hunks)Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/App/SceneDelegate.swift(1 hunks)Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/Resource/Assets.xcassets/AccentColor.colorset/Contents.json(1 hunks)Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/Resource/Assets.xcassets/AppIcon.appiconset/Contents.json(1 hunks)Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/Resource/Assets.xcassets/Contents.json(1 hunks)Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/Resource/Assets.xcassets/icon_login_apple.imageset/Contents.json(1 hunks)Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/Resource/Assets.xcassets/icon_login_kakao.imageset/Contents.json(1 hunks)Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/Resource/Assets.xcassets/image_login_logo.imageset/Contents.json(1 hunks)Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/Resource/Base.lproj/LaunchScreen.storyboard(1 hunks)Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/Resource/Info.plist(1 hunks)Poppool/PresentationLayer/LoginFeature/LoginFeatureInterface/Source/Factory/LoginFactory.swift(1 hunks)Poppool/PresentationLayer/Presentation/Presentation.xcodeproj/project.pbxproj(15 hunks)Poppool/PresentationLayer/Presentation/Presentation/Scene/Detail/DetailReactor.swift(4 hunks)Poppool/PresentationLayer/Presentation/Presentation/Scene/Login/Main/LoginController.swift(0 hunks)Poppool/PresentationLayer/Presentation/Presentation/Scene/Login/Main/LoginReactor.swift(0 hunks)Poppool/PresentationLayer/Presentation/Presentation/Scene/Login/Main/LoginView.swift(0 hunks)Poppool/PresentationLayer/Presentation/Presentation/Scene/Login/Sub/SubLoginController.swift(0 hunks)Poppool/PresentationLayer/Presentation/Presentation/Scene/Login/Sub/SubLoginReactor.swift(0 hunks)Poppool/PresentationLayer/Presentation/Presentation/Scene/Login/Sub/SubLoginView.swift(0 hunks)Poppool/PresentationLayer/Presentation/Presentation/Scene/MyPage/FAQ/FactoryImpl/FAQFactoryImpl.swift(1 hunks)Poppool/PresentationLayer/Presentation/Presentation/Scene/MyPage/Main/MyPageReactor.swift(2 hunks)Poppool/PresentationLayer/Presentation/Presentation/Scene/SignUp/FactoryImpl/SignUpFactoryImpl.swift(1 hunks)Poppool/PresentationLayer/Presentation/Presentation/Scene/SignUp/Main/SignUpMainReactor.swift(1 hunks)Poppool/PresentationLayer/Presentation/Presentation/Scene/Splash/SplashController.swift(2 hunks)Poppool/PresentationLayer/Presentation/Presentation/Scene/TabbarController/FactoryImpl/WaveTabbarFactoryImpl.swift(1 hunks)Poppool/PresentationLayer/Presentation/PresentationInterface/Factory/FAQFactory.swift(1 hunks)Poppool/PresentationLayer/Presentation/PresentationInterface/Factory/SignUpFactory.swift(1 hunks)Poppool/PresentationLayer/Presentation/PresentationInterface/Factory/WaveTabbarFactory.swift(1 hunks)Poppool/PresentationLayer/Presentation/PresentationTesting/Factory/FAQFactoryMock.swift(1 hunks)Poppool/PresentationLayer/Presentation/PresentationTesting/Factory/SignUpFactoryMock.swift(1 hunks)Poppool/PresentationLayer/Presentation/PresentationTesting/Factory/WaveTabbarFactoryMock.swift(1 hunks)Poppool/PresentationLayer/SearchFeature/SearchFeature.xcodeproj/project.pbxproj(2 hunks)Poppool/fastlane/Matchfile(1 hunks)
💤 Files with no reviewable changes (6)
- Poppool/PresentationLayer/Presentation/Presentation/Scene/Login/Main/LoginView.swift
- Poppool/PresentationLayer/Presentation/Presentation/Scene/Login/Sub/SubLoginView.swift
- Poppool/PresentationLayer/Presentation/Presentation/Scene/Login/Sub/SubLoginController.swift
- Poppool/PresentationLayer/Presentation/Presentation/Scene/Login/Sub/SubLoginReactor.swift
- Poppool/PresentationLayer/Presentation/Presentation/Scene/Login/Main/LoginController.swift
- Poppool/PresentationLayer/Presentation/Presentation/Scene/Login/Main/LoginReactor.swift
🧰 Additional context used
🧬 Code Graph Analysis (10)
Poppool/PresentationLayer/Presentation/PresentationInterface/Factory/FAQFactory.swift (1)
Poppool/PresentationLayer/Presentation/Presentation/Scene/MyPage/FAQ/FactoryImpl/FAQFactoryImpl.swift (1)
make(7-12)
Poppool/PresentationLayer/LoginFeature/LoginFeatureInterface/Source/Factory/LoginFactory.swift (1)
Poppool/PresentationLayer/LoginFeature/LoginFeature/Factory/LoginFactory.swift (1)
make(12-26)
Poppool/PresentationLayer/Presentation/PresentationTesting/Factory/FAQFactoryMock.swift (2)
Poppool/PresentationLayer/Presentation/PresentationTesting/Factory/SignUpFactoryMock.swift (1)
make(8-10)Poppool/PresentationLayer/Presentation/PresentationTesting/Factory/WaveTabbarFactoryMock.swift (1)
make(9-11)
Poppool/PresentationLayer/Presentation/PresentationInterface/Factory/WaveTabbarFactory.swift (1)
Poppool/PresentationLayer/Presentation/Presentation/Scene/TabbarController/FactoryImpl/WaveTabbarFactoryImpl.swift (1)
make(8-10)
Poppool/PresentationLayer/Presentation/PresentationTesting/Factory/WaveTabbarFactoryMock.swift (2)
Poppool/PresentationLayer/Presentation/PresentationTesting/Factory/FAQFactoryMock.swift (1)
make(8-10)Poppool/PresentationLayer/Presentation/PresentationTesting/Factory/SignUpFactoryMock.swift (1)
make(8-10)
Poppool/PresentationLayer/LoginFeature/LoginFeature/Factory/LoginFactory.swift (1)
Poppool/PresentationLayer/Presentation/Presentation/Scene/SignUp/FactoryImpl/SignUpFactoryImpl.swift (1)
make(12-22)
Poppool/PresentationLayer/Presentation/PresentationInterface/Factory/SignUpFactory.swift (1)
Poppool/PresentationLayer/Presentation/Presentation/Scene/SignUp/FactoryImpl/SignUpFactoryImpl.swift (1)
make(12-22)
Poppool/PresentationLayer/Presentation/Presentation/Scene/Splash/SplashController.swift (2)
Poppool/CoreLayer/Infrastructure/Infrastructure/Service/KeyChainService.swift (1)
saveToken(61-92)Poppool/PresentationLayer/LoginFeature/LoginFeature/Factory/LoginFactory.swift (1)
make(12-26)
Poppool/PresentationLayer/Presentation/PresentationTesting/Factory/SignUpFactoryMock.swift (2)
Poppool/PresentationLayer/Presentation/PresentationTesting/Factory/FAQFactoryMock.swift (1)
make(8-10)Poppool/PresentationLayer/Presentation/PresentationTesting/Factory/WaveTabbarFactoryMock.swift (1)
make(9-11)
Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/App/AppDelegate.swift (1)
Poppool/Poppool/Application/AppDelegate.swift (4)
application(21-32)application(35-37)registerDependencies(43-98)registerFactory(100-109)
🔇 Additional comments (43)
Poppool/PresentationLayer/SearchFeature/SearchFeature.xcodeproj/project.pbxproj (1)
717-717: App Store 배포를 위한 코드 서명 설정이 올바르게 구성되었습니다.Release 빌드 구성에서 개발용 설정에서 배포용 설정으로 적절히 변경되었습니다:
- 코드 서명 identity가 "iPhone Distribution"으로 설정
- 프로비저닝 프로파일이 App Store 배포용으로 변경
이 변경사항들은 App Store 제출을 위한 표준 구성이며, Debug 빌드에는 영향을 주지 않아 개발 워크플로우가 유지됩니다.
Also applies to: 738-738
Poppool/fastlane/Matchfile (1)
7-7: 와일드카드 번들 ID만으로 데모 타깃 서명 가능 여부 확인 필요
"com.poppoolIOS.*"와일드카드 프로비저닝 프로파일은 Push Notification 같이 특정 Entitlement 가 필요한 앱에서는 빌드/배포용으로 사용이 불가합니다.
LoginFeatureDemo타깃이 해당 기능(푸시, 앱 그룹 등)을 사용하는 경우, 기존의 명시적"com.poppoolIOS.poppool.LoginFeatureDemo"식별자를 유지하거나 별도 개발/배포용 프로비저닝을 준비해야 합니다.프로덕션/테스트 환경별로 프로비저닝 프로파일이 정상 매칭되는지 Xcode 아카이브 단계에서 한 번 더 확인해 주세요.
Poppool/Poppool.xcworkspace/contents.xcworkspacedata (1)
24-26: Workspace 경로 확인
group:LoginFeature/LoginFeature.xcodeproj경로가 루트에서 상대경로로 정확히 맞춰졌는지, CI 환경(예:xcodebuild -workspace ...)에서도 인식되는지 점검해 주세요.
팀원 혹은 CI 서버에서 “project cannot be found” 오류가 발생할 수 있습니다.Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/Resource/Assets.xcassets/Contents.json (1)
1-6: LGTM에셋 카탈로그 메타데이터 기본값으로 문제 없습니다.
Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/Resource/Assets.xcassets/icon_login_apple.imageset/Contents.json (1)
1-12: SVG 파일 호환성 확인현재 Xcode(14 이하)는
.svg벡터 에셋을 공식적으로 빌드 타임에 래스터라이즈하지 못하므로 컴파일 오류가 발생할 수 있습니다.
일반적으로Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/Resource/Assets.xcassets/image_login_logo.imageset/Contents.json (1)
1-12: SVG 파일 호환성 확인위 Apple 로그인 아이콘과 동일하게
.svg사용 시 컴파일 가능 여부를 재확인해 주세요. 문제가 있다면Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/Resource/Assets.xcassets/icon_login_kakao.imageset/Contents.json (1)
1-12: 표준 에셋 카탈로그 구성이 올바릅니다.카카오 로그인 아이콘에 대한 에셋 카탈로그 JSON 구성이 Apple의 표준 형식을 올바르게 따르고 있습니다.
Poppool/CoreLayer/Infrastructure/Infrastructure/Service/UserDefaultService.swift (1)
74-76: 인증 관련 UserDefault 키 추가가 적절합니다.새로 추가된
userID,socialType,lastLogin키들은 로그인 기능 모듈화와 툴팁 중복 문제 해결을 위해 필요한 사용자 인증 상태 관리를 지원합니다. 기존 네이밍 컨벤션을 잘 따르고 있습니다.Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/Resource/Assets.xcassets/AccentColor.colorset/Contents.json (1)
1-11: 표준 컬러 에셋 구성입니다.LoginFeatureDemo 앱을 위한 표준 accent color 에셋 카탈로그 구성입니다. 구체적인 컬러 값이 지정되지 않아 시스템 기본값을 사용하게 됩니다.
Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/Resource/Assets.xcassets/AppIcon.appiconset/Contents.json (1)
1-35: iOS 앱 아이콘 구성이 적절합니다.기본, 다크 모드, 틴티드 모드를 포함한 포괄적인 앱 아이콘 구성으로 Apple의 현재 가이드라인을 올바르게 따르고 있습니다. LoginFeatureDemo 앱을 위한 표준 설정입니다.
Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/Resource/Info.plist (1)
5-22: 플리스트 자체는 문제없음
SceneDelegate설정 및 멀티-씬 비활성화가 의도와 일치해 보입니다.Poppool/PresentationLayer/Presentation/PresentationInterface/Factory/FAQFactory.swift (1)
1-5: UIKit import 누락 가능성 확인
BaseViewController가DesignSystem모듈에 존재한다면 괜찮지만, 만약 UIKit 상속 계층에 의존한다면import UIKit누락 시 컴파일 오류가 발생합니다. 빌드 통과 여부를 한 번 더 확인해 주세요.Poppool/CoreLayer/Infrastructure/Infrastructure/Service/KeyChainService.swift (1)
97-98:deleteToken에도 동일한@discardableResult주의삭제 실패가 무시될 경우 보안 토큰이 예상보다 오래 남아 있을 수 있습니다. 위 저장 메서드와 동일한 검토가 필요합니다.
Poppool/Poppool.xcodeproj/project.pbxproj (1)
36-40: Framework 임베드 순서 변경 시 CodeSign 충돌 여부 확인새로 추가된
LoginFeature·LoginFeatureInterface프레임워크가 Embed 단계에 들어왔는데, 중복 서명 속성이 다른 경우(예: ‘RemoveHeadersOnCopy’) 간헐적 빌드 실패가 있을 수 있습니다. CI 빌드 확인 바랍니다.Poppool/Poppool/Application/AppDelegate.swift (2)
8-9: 새로운 LoginFeature 모듈 import가 적절하게 추가되었습니다.모듈화된 로그인 기능을 위한 import문이 올바르게 추가되었습니다.
105-108: 팩토리 등록이 일관된 패턴으로 구현되었습니다.새로운 팩토리들(LoginFactory, SignUpFactory, WaveTabbarFactory, FAQFactory)이 기존 팩토리 등록 패턴과 일관되게 DI 컨테이너에 등록되었습니다. 프로토콜-구현체 매핑이 명확하고 적절합니다.
Poppool/PresentationLayer/Presentation/PresentationTesting/Factory/FAQFactoryMock.swift (1)
4-11: 테스트용 Mock 팩토리가 적절하게 구현되었습니다.FAQFactoryMock이 다른 Mock 팩토리들과 일관된 패턴으로 구현되어 있으며, 테스트 목적에 적합한 간단한 구조를 가지고 있습니다.
Poppool/Poppool.xcworkspace/xcshareddata/swiftpm/Package.resolved (1)
27-28: 패키지 업데이트 확인 완료Kakao iOS SDK(2.24.1→2.24.5)와 NMapsMap(3.21.0→3.22.0)가 모든 관련 파일에서 정상적으로 import되고 있습니다. 마이너 버전 업데이트이므로 주요 breaking change 가능성은 낮습니다. 아래 위치들을 점검했으며, 실제 CI 빌드 및 주요 기능(로그인, 지도 표시) 테스트 후 머지를 진행해주세요.
LoginFeature
- Poppool/PresentationLayer/LoginFeature/LoginFeature/Login/LoginReactor.swift
- Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/App/AppDelegate.swift
- Poppool/PresentationLayer/LoginFeature/LoginFeature/Factory/LoginFactory.swift
Map 기능
- Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/MapView/MapViewController.swift
- Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/MapView/MapView.swift
- Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/MapView/MapMarker.swift
- Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/FindMap/MapGuideView/FullScreenMapViewController.swift
- Poppool/PresentationLayer/Presentation/Presentation/Scene/Map/FindMap/MapGuideView/MapGuideViewController.swift
공통 유틸리티
- Poppool/PresentationLayer/Presentation/Presentation/Utills/Common/RegionDefinitions.swift
- Poppool/PresentationLayer/Presentation/Presentation/Utills/Common/NMFMapViewDelegateProxy.swift
머지 전 CI 빌드 및 로그인·지도 기능 테스트 완료를 권장드립니다.
Poppool/PresentationLayer/Presentation/PresentationTesting/Factory/WaveTabbarFactoryMock.swift (1)
6-12: TabBar Mock 팩토리가 일관된 패턴으로 구현되었습니다.WaveTabbarFactoryMock이 다른 Mock 팩토리들과 동일한 구조로 구현되어 있으며, 테스트에서 실제 WaveTabBarController 없이도 UITabBarController를 제공할 수 있어 적절합니다.
Poppool/PresentationLayer/Presentation/Presentation/Scene/TabbarController/FactoryImpl/WaveTabbarFactoryImpl.swift (1)
5-11: WaveTabbar 팩토리 구현이 깔끔하게 완성되었습니다.WaveTabbarFactoryImpl이 프로토콜을 정확히 구현하고 있으며, WaveTabBarController 인스턴스를 생성하는 간단하고 명확한 팩토리 패턴이 적용되었습니다.
Poppool/PresentationLayer/LoginFeature/LoginFeature/Login/LastLoginView.swift (2)
201-202: 툴팁 중복 생성 문제가 적절히 해결되었습니다기존
LastLoginView인스턴스들을 제거한 후 새로운 툴팁을 추가하는 로직으로 중복 툴팁 표시 문제를 효과적으로 해결했습니다.
185-185: 코드 포맷팅이 일관성 있게 개선되었습니다주석 처리된 코드의 들여쓰기가 정리되어 가독성이 향상되었습니다.
Poppool/PresentationLayer/LoginFeature/LoginFeatureInterface/Source/Factory/LoginFactory.swift (2)
5-8: 로그인 시나리오를 위한 명확한 열거형 정의
main과sub케이스로 로그인 시나리오를 명확히 구분하여 팩토리에서 적절한 뷰 컨트롤러를 생성할 수 있도록 설계되었습니다.
10-15: 깔끔하고 확장 가능한 팩토리 인터페이스 설계팩토리 패턴을 활용해 로그인 뷰 컨트롤러 생성 로직을 모듈화하고,
text매개변수를 통해 다양한 메시지를 지원할 수 있도록 설계되었습니다.Poppool/PresentationLayer/Presentation/Presentation/Scene/MyPage/Main/MyPageReactor.swift (2)
6-6: 모듈 간 의존성 관리가 적절히 개선되었습니다
LoginFeatureInterface모듈을 import하여 팩토리 기반 로그인 기능을 활용할 수 있도록 설정되었습니다.
271-276: 팩토리 패턴을 활용한 모듈화가 잘 구현되었습니다의존성 주입을 통해
LoginFactory를 주입받고, 팩토리를 사용하여 로그인 뷰 컨트롤러를 생성하는 방식으로 기존의 수동 인스턴스 생성 방식을 개선했습니다. 사용자에게 적합한 메시지와 함께 서브 로그인 화면을 제공합니다.Poppool/PresentationLayer/Presentation/Presentation/Scene/MyPage/FAQ/FactoryImpl/FAQFactoryImpl.swift (1)
4-13: 일관성 있는 팩토리 패턴 구현FAQ 기능을 위한 팩토리 구현이 다른 팩토리들과 동일한 패턴을 따르며, 뷰 컨트롤러와 리액터를 적절히 구성하여 반환하고 있습니다.
Poppool/PresentationLayer/Presentation/PresentationInterface/Factory/SignUpFactory.swift (1)
3-5: 회원가입 플로우에 적합한 팩토리 인터페이스 설계회원가입 과정에 필요한
isFirstResponder와authrizationCode매개변수를 받아BaseTabmanController를 반환하는 구조로, 탭 기반의 회원가입 UI와 잘 부합하는 설계입니다.Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/Resource/Base.lproj/LaunchScreen.storyboard (1)
1-25: 표준 LaunchScreen 스토리보드가 올바르게 구현되었습니다.LoginFeatureDemo 앱을 위한 기본 런치 스크린이 표준 iOS 규격에 맞게 구현되어 있습니다.
Poppool/PresentationLayer/DesignSystem/DesignSystem/Components/PPLabel.swift (1)
6-7: 기본값 매개변수 추가로 사용성이 개선되었습니다.
style과fontSize에 기본값을 제공함으로써 PPLabel 컴포넌트의 사용성이 향상되었습니다. 선택된 기본값들(.regular, 12pt)도 적절합니다.Poppool/PresentationLayer/Presentation/PresentationTesting/Factory/SignUpFactoryMock.swift (1)
9-10: 테스트용 Mock 팩토리가 적절히 구현되었습니다.다른 Mock 팩토리들과 일관된 패턴을 따르고 있어 좋습니다. 테스트 목적으로 단순한 BaseTabmanController 인스턴스를 반환하는 것이 적절합니다.
Poppool/PresentationLayer/Presentation/Presentation/Scene/Splash/SplashController.swift (1)
68-68: 검증 완료: 클로저 내부 @dependency 사용 패턴 일관성 확인프로젝트 전반에 걸쳐 클로저 내부에서
@Dependency를 사용하는 동일한 패턴이 다수 발견되었으며, Swift 5.4 이상의 로컬 프로퍼티 래퍼 지원을 활용한 의도된 구현입니다. DIContainer가 매번 새로운 인스턴스를 제공하도록 설계되어 있어, 클로저 호출 시점마다 적절히 의존성을 해제·재주입하며 스코프 문제가 발생하지 않습니다. 추가 수정이나 검증은 필요하지 않습니다.Poppool/PresentationLayer/Presentation/Presentation/Scene/SignUp/FactoryImpl/SignUpFactoryImpl.swift (1)
12-22: 팩토리 구현이 올바르게 되어 있습니다.SignUpFactory 프로토콜이 적절히 구현되었으며, 의존성 주입 패턴과 리액터 설정이 올바르게 이루어졌습니다. 다른 팩토리 구현체들과 일관된 구조를 유지하고 있습니다.
Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/App/SceneDelegate.swift (1)
1-26: LGTM! 표준 iOS 패턴을 잘 따르고 있습니다.LoginFeatureDemo 앱의 SceneDelegate 구현이 올바릅니다. 의존성 주입 패턴과 UIWindow 설정이 적절하게 구현되어 있습니다.
Poppool/PresentationLayer/Presentation/Presentation/Scene/Detail/DetailReactor.swift (1)
6-6: 의존성 주입 패턴 도입 승인LoginFeatureInterface 모듈 추가가 적절합니다.
Poppool/PresentationLayer/LoginFeature/LoginFeature/Factory/LoginFactory.swift (1)
8-27: 팩토리 구현이 우수합니다LoginFactory 프로토콜 구현이 올바르게 되어 있습니다. DIContainer를 통한 의존성 해결과 뷰 컨트롤러 생성 로직이 적절합니다.
Poppool/PresentationLayer/LoginFeature/LoginFeature.xcodeproj/xcshareddata/xcschemes/LoginFeatureDemo.xcscheme (1)
1-78: 표준 Xcode 스킴 설정LoginFeatureDemo 타겟에 대한 표준 Xcode 스킴 구성이 적절합니다.
Poppool/PresentationLayer/LoginFeature/LoginFeature/Login/LoginView.swift (2)
9-49: UI 컴포넌트 구성이 우수합니다Then 라이브러리를 활용한 UI 컴포넌트 설정이 깔끔하고 일관성 있게 구현되었습니다.
140-159: 공개 메서드 구현이 적절합니다setTitle과 setCloseButton 메서드가 LoginSceneType에 따른 UI 설정을 잘 처리하고 있습니다.
Poppool/PresentationLayer/LoginFeature/LoginFeature/Login/LoginViewController.swift (1)
63-73: 강제 언래핑 대신 안전한 옵셔널 처리를 사용하세요
reactor?.userDefaultService.fetch(keyType: .lastLogin)에서 reactor가 nil일 수 있으므로, guard let 또는 if let을 사용하여 안전하게 처리하는 것이 좋습니다.override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - if let lastLogin = reactor?.userDefaultService.fetch(keyType: .lastLogin) { + guard let reactor = reactor, + let lastLogin = reactor.userDefaultService.fetch(keyType: .lastLogin) else { return } + switch lastLogin { case "kakao": mainView.kakaoButton.showToolTip(color: .w100, direction: .pointDown) case "apple": mainView.appleButton.showToolTip(color: .w100, direction: .pointUp) default: break } - } }Likely an incorrect or invalid review comment.
Poppool/PresentationLayer/LoginFeature/LoginFeature.xcodeproj/project.pbxproj (1)
595-595: DEVELOPMENT_TEAM 설정이 비어있습니다여러 타겟에서 DEVELOPMENT_TEAM이 빈 문자열로 설정되어 있습니다. 빌드 및 배포 시 문제가 될 수 있습니다.
개발팀 설정이 의도적으로 비워진 것인지 확인이 필요합니다.
Also applies to: 635-635, 751-751, 787-787
Poppool/PresentationLayer/Presentation/Presentation.xcodeproj/project.pbxproj (2)
279-279: 프로젝트 설정이 일관성 있게 업데이트되었습니다LastSwiftUpdateCheck가 1630에서 1640으로 업데이트되었습니다. 새로운 PresentationTesting 타겟 추가와 함께 적절한 변경입니다.
187-210: PresentationTesting 타겟이 적절히 구성되었습니다새로운 테스팅 프레임워크 타겟이 올바른 의존성과 빌드 설정으로 추가되었습니다.
Poppool/CoreLayer/Infrastructure/Infrastructure/Service/KeyChainService.swift
Show resolved
Hide resolved
Poppool/PresentationLayer/LoginFeature/LoginFeature.xcodeproj/project.pbxproj
Outdated
Show resolved
Hide resolved
Poppool/PresentationLayer/LoginFeature/LoginFeature/Login/LoginReactor.swift
Outdated
Show resolved
Hide resolved
Poppool/PresentationLayer/LoginFeature/LoginFeature/Login/LoginReactor.swift
Show resolved
Hide resolved
Poppool/PresentationLayer/LoginFeature/LoginFeature/Login/LoginReactor.swift
Show resolved
Hide resolved
Poppool/PresentationLayer/LoginFeature/LoginFeature/Login/LoginReactor.swift
Outdated
Show resolved
Hide resolved
Poppool/PresentationLayer/LoginFeature/LoginFeature/Login/LoginViewController.swift
Show resolved
Hide resolved
Poppool/PresentationLayer/LoginFeature/LoginFeatureDemo/App/AppDelegate.swift
Show resolved
Hide resolved
Poppool/PresentationLayer/Presentation/Presentation/Scene/Splash/SplashController.swift
Outdated
Show resolved
Hide resolved
Poppool/PresentationLayer/Presentation/PresentationTesting/Factory/SignUpFactoryMock.swift
Outdated
Show resolved
Hide resolved
- 로그아웃이나 회원탈퇴시 정보 제거가 이루어지지 않고 있었음 - 해당 로직을 추가함
- View에서 Reactor의 인스턴스(userDefautService)를 직접 접근하는것을 방지 - Rx의 ViewController LifeCycle을 이용하도록 수정
…m/PopPool/iOS into fix/#160-recent-login-duplication
zzangzzangguy
left a comment
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.
궁금한점이 몇군데 있었는데 코드래빗이 짚어줬군요..
툴팁상태관리가 VC에 있는듯한데 따로 상태값 별로 분리해줘도 좋을듯합니다!
LGTM!
@zzangzzangguy 어느 부분을 얘기주시는건지 코드에 코멘트 남겨주실 수 있으실까요? |
📌 이슈
✅ 작업 사항
🚀 테스트 방식
Poppool 메인 앱 실행 → 로그인 툴팁 중복 상황 확인
👀 ETC (추후 개발해야 할 것, 참고자료 등) ->
로그인 툴팁 중복이 발생했던 상황 기재
Summary by CodeRabbit
신규 기능
리팩터
버그 수정/개선
문서 및 설정