-
Notifications
You must be signed in to change notification settings - Fork 0
[Feat] 로그인, 온보딩, 커뮤니티 UseCase 및 소셜 로그인, 자동 로그인 로직 구현 #114
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
JinUng41
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.
고생하셨습니다.
나날이 성장해 가시는 유진님의 모습이 이젠 무섭네요..!
멋있으세요. 저를 뛰어넘으시고, 리드까지 하시면 좋을 것 같아요! 👍
Wable-iOS/App/SceneDelegate.swift
Outdated
| .sink { result in | ||
| switch result { | ||
| case .finished: | ||
| break | ||
| case .failure(_): | ||
| self.configureLoginScreen() | ||
| } |
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.
제가 알기로 receiveCompletion으로 알고 있는데, 변수명을 completion으로 하는 건 어떻게 생각하세요?
물론 result도 비슷한 느낌이긴 하나, 애초 메서드명을 따라가는 것이 더 낫다고 판단되어서 말씀드려 봅니다.
if case let을 사용하면 아래와 같이 표현할 수도 있어요.
.sink { [weak self] result in
if case let .failure(error) = result {
self?.configureLoginScreen()
}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.
반영했습니다!
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.
로직이 추가로 구현될거라 일단 임시로 저렇게 처리해두었습니다 !! 다른 곳에서 한번 활용해보도록 하겠습니닷 ... 감사합니다!!
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.
Core로 옮긴 것이 맞는 판단 같습니다. 굿잡 👍
| protocol AuthProvider { | ||
| func authenticate() -> AnyPublisher<String?, WableError> | ||
| } |
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.
authenticate 메서드명 좋은 것 같습니다.
| func updateActiveUserID(forUserID userID: Int?) { | ||
| if let userID = userID { | ||
| try? userDefaults.setValue(userID, for: Keys.activeUserID) | ||
| } | ||
| } |
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.
updateActiveUserID(_:)으로 메서드 명을 바꾸는 것은 어떤가요?
메서드 명에서 이미 UserID가 있기 때문에 파라미터 레이블로 forUserID는 중복되는 느낌이 들었습니다.
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.
반영했습니다!
| final class UpdateUserProfileUseCase { | ||
| let repository: ProfileRepository | ||
|
|
||
| init(repository: ProfileRepository) { | ||
| self.repository = repository | ||
| } | ||
| } | ||
|
|
||
| extension UpdateUserProfileUseCase { | ||
| func execute(profile: UserProfile, isPushAlarmAllowed: Bool) -> AnyPublisher<Void, WableError> { | ||
| return repository.updateUserProfile(profile: profile, isPushAlarmAllowed: isPushAlarmAllowed) | ||
| } | ||
| } |
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.
프로필을 수정하는 화면은 사용자 프로필을 보여주는 탭에서 사용되는게 맞는 부분인 것 같아요.
온보딩에서 사용자의 프로필을 구성하도록 사용되는 행위니까 CreateUserProfile은 어떨까 싶어요.
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.
반영했습니다! 감사합니닷
| func authenticate() -> AnyPublisher<String?, WableError> { | ||
| let UserAPI = UserApi.self |
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.
typealias를 이용하여 UserApi를 KakaoUserAPI로 선언하는 것은 어떨까요?
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.
문과세요? 캬...
| return Future<String?, WableError> { promise in | ||
| if UserAPI.isKakaoTalkLoginAvailable() { | ||
| UserAPI.shared.loginWithKakaoTalk { [weak self] (oauthToken, error) in | ||
| self?.handleKakaoAuthResult(oauthToken: oauthToken, error: error, promise: promise) | ||
| } | ||
| } else { | ||
| UserAPI.shared.loginWithKakaoAccount { [weak self] (oauthToken, error) in | ||
| self?.handleKakaoAuthResult(oauthToken: oauthToken, error: error, promise: promise) | ||
| } | ||
| } | ||
| } | ||
| .eraseToAnyPublisher() |
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.
아래와 같이 삼항 연산자를 이용해 보는 것은 어떠세요?
return Future<String?, WableError> { promise in
let loginMethod = UserApi.isKakaoTalkLoginAvailable()
? UserApi.shared.loginWithKakaoTalk
: UserApi.shared.loginWithKakaoAccount
loginMethod { [weak self] oauthToken, error in
self?.handleKakaoAuthresult(oauthToken: oauthToken, error: error, promise: promise)
}
}
.eraseToAnyPulisher()| if let token = oauthToken?.accessToken { | ||
| try? tokenStorage.save(token, for: .kakaoAccessToken) | ||
| } else { |
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.
try에 대한 에러처리를 하지 않아도 괜찮은지 궁금합니다!
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.
반영했습니다!
[Feat] 로그인, 온보딩, 커뮤니티 UseCase 및 소셜 로그인, 자동 로그인 로직 구현
👻 PULL REQUEST
📄 작업 내용
AuthProvider를 통해 추상화를 진행했어요.UseCase폴더링을 진행했어요.CombineCocoa라이브러리를 추가했어요.Bundle익스텐션에kakaoAppKey,amplitudeAppKey가 추가 선언됨에 따라Bundle폴더를Core레이어로 이동했어요.kakaoAppKey는AppDelegate에서 SDK 초기화 시 사용되기 때문에 익스텐션이Core로 이동되어야 한다고 판단했어요.kakaoAppKey를 옮겨오는 과정에서amplitudeAppKey도 함께 선언했어요.💻 주요 코드 설명
애플 로그인, 카카오 로그인 구현 (
FetchUserAuthUseCase구현)Infra레이어의KakaoAuthProvider와AppleAuthProvider로 숨겨 구현했습니다.KakaoSDKAuth,KakaoSDKUser,AuthenticationServices를 import해야 하기 때문에 Domain 레이어에서 추가적인 의존성을 가지는 것이 클린 아키텍처에 맞지 않다고 생각했습니다.AuthProvider라는 공통 프로토콜을 선언해 Data 레이어에 추상화한 후 Infra 레이어에서 각각의Provider가AuthProvider프로토콜을 채택하도록 구현했습니다.KakaoAuthProvider파일의authenticate()메서드)handleKakaoAuthResult()메서드 내에서 KeychainStorage에 저장합니다.TokenType에.kakaoAccessToken이라는 enum 케이스를 추가해 저장했습니다.userName을 넘겨야 하기 때문에 유저의 이름을 받아오도록 구현했습니다.ASAuthorizationControllerDelegate,ASAuthorizationControllerPresentationContextProviding프로토콜을 채택해 필수적으로 요구되는 메서드들을 구현했습니다.LoginRepository의 실구현체인LoginRepositoryImpl에서 해당 provider를SocialPlatform: AuthProvider의 배열 형식으로 초기화하도록 했습니다.fetchUserAuth에서는 provider를 통해 인증 로직을 수행한 후 받아온 결과값을 이용해 서버 통신을 수행합니다.자동 로그인 로직 구현 (미완성)
UserSessionRepository에서 자동 로그인 여부를 체크할 수 있는checkAutoLogin()메서드를 추가했습니다.scene(_ scene: UIScene, willConnectTo...메서드에서 호출되어 토큰 존재 확인 시 메인 화면으로 전환되도록 구현되어 있습니다.📚 참고자료
버터플라이 아키텍처를 소개합니다
👀 기타 더 이야기해볼 점
TODO로 남겨두었습니다. 최대한 빠르게 이슈 생성해 반영하겠습니다!🔗 연결된 이슈