From f309b1a579e43c5408f794cf403f3e0fb098232e Mon Sep 17 00:00:00 2001 From: Bibi-urssu Date: Sun, 7 Sep 2025 22:29:59 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20postSignIn=20API=20=EC=97=B0?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/Component/LMTextField.swift | 4 ++++ .../Sources/View/Login/SignInView.swift | 19 ++++++++++++------- Projects/Data/Sources/DTO/LoginDTO.swift | 12 ++++++++++++ .../Sources/Repository/LoginRepository.swift | 10 +++++----- .../Sources/Repository/SignRepository.swift | 18 ++++++++++++++++-- .../RepositoryProtocol/LoginRepository.swift | 4 ++-- .../RepositoryProtocol/SignRepository.swift | 1 + .../Sources/UseCase/Login/LoginUseCase.swift | 8 ++++---- .../Sources/UseCase/Login/SignUseCase.swift | 5 +++++ Projects/Domain/Sources/VO/LoginVO.swift | 19 +++++++++++-------- .../Sources/View/SignInViewController.swift | 19 ++++++++++++++++--- .../Sources/ViewModel/SignViewModel.swift | 10 ++++++++++ 12 files changed, 98 insertions(+), 31 deletions(-) diff --git a/Projects/CommonUI/Sources/Component/LMTextField.swift b/Projects/CommonUI/Sources/Component/LMTextField.swift index 8ff54c3..6bc57c2 100644 --- a/Projects/CommonUI/Sources/Component/LMTextField.swift +++ b/Projects/CommonUI/Sources/Component/LMTextField.swift @@ -52,4 +52,8 @@ public class LMTextField: UITextField { $0.height.equalTo(55) } } + + public func currentText() -> String { + return self.text ?? "" + } } diff --git a/Projects/CommonUI/Sources/View/Login/SignInView.swift b/Projects/CommonUI/Sources/View/Login/SignInView.swift index b986f98..70deb08 100644 --- a/Projects/CommonUI/Sources/View/Login/SignInView.swift +++ b/Projects/CommonUI/Sources/View/Login/SignInView.swift @@ -19,12 +19,13 @@ open class SignInView: UIView { } var textFieldStackView = UIStackView() - var idTextField = LMTextField() - var passwordTextField = LMTextField() - var loginButton = LMButton(textColor: CommonUIAssets.LMBlack, + public var idTextField = LMTextField() + public var passwordTextField = LMTextField() + var signInButton = LMButton(textColor: CommonUIAssets.LMBlack, bgColor: CommonUIAssets.LMOrange1) var signUpButton = UIButton() + public let signInTapped = PublishRelay() public let signUpTapped = PublishRelay() private let disposeBag = DisposeBag() @@ -40,6 +41,10 @@ open class SignInView: UIView { } func bindEvents() { + signInButton.rx.tap + .bind(to: signInTapped) + .disposed(by: disposeBag) + signUpButton.rx.tap .bind(to: signUpTapped) .disposed(by: disposeBag) @@ -63,7 +68,7 @@ open class SignInView: UIView { $0.isSecureTextEntry = true } - loginButton = loginButton.then { + signInButton = signInButton.then { $0.setTitle("로그인", for: .normal) } @@ -84,7 +89,7 @@ open class SignInView: UIView { } func initUI() { - [logoView, textFieldStackView, loginButton, signUpButton] + [logoView, textFieldStackView, signInButton, signUpButton] .forEach { addSubview($0) } [idTextField, passwordTextField] @@ -102,14 +107,14 @@ open class SignInView: UIView { $0.height.equalTo(130) } - loginButton.snp.makeConstraints { + signInButton.snp.makeConstraints { $0.top.equalTo(textFieldStackView.snp.bottom).offset(33) $0.centerX.equalToSuperview() $0.horizontalEdges.equalToSuperview().inset(20) } signUpButton.snp.makeConstraints { - $0.top.equalTo(loginButton.snp.bottom).offset(35) + $0.top.equalTo(signInButton.snp.bottom).offset(35) $0.centerX.equalToSuperview() $0.height.equalTo(27) } diff --git a/Projects/Data/Sources/DTO/LoginDTO.swift b/Projects/Data/Sources/DTO/LoginDTO.swift index 50d10a5..d92df1c 100644 --- a/Projects/Data/Sources/DTO/LoginDTO.swift +++ b/Projects/Data/Sources/DTO/LoginDTO.swift @@ -10,9 +10,21 @@ import Domain public struct LoginDTO: Decodable { public let accessToken: String + public let refreshToken: String } extension LoginDTO { + func getMessage() -> LoginVO { + return .init(accessToken: accessToken, + refreshToken: refreshToken) + } +} + +public struct GoogleLoginDTO: Decodable { + public let accessToken: String +} + +extension GoogleLoginDTO { // func toDomain() -> CourseVO { // return CourseVO(courseLv: 1, // courseDescription: "courseDescription", diff --git a/Projects/Data/Sources/Repository/LoginRepository.swift b/Projects/Data/Sources/Repository/LoginRepository.swift index d02a447..26f7786 100644 --- a/Projects/Data/Sources/Repository/LoginRepository.swift +++ b/Projects/Data/Sources/Repository/LoginRepository.swift @@ -13,17 +13,17 @@ import Foundation public class DefaultLoginRepository: LoginRepository { public init() {} - public func postGoogleLogin() -> Single { + public func postGoogleLogin() -> Single { return request( endpoint: "/oauth2/authorization/google", - responseType: LoginDTO.self + responseType: GoogleLoginDTO.self ) .map { dto in - return LoginVO(accessToken: "") + return GoogleLoginVO(accessToken: "") } } - public func postAppleLogin(userName: String?, identityToken: String) -> Single { + public func postAppleLogin(userName: String?, identityToken: String) -> Single { let params: Parameters = [ "userName": userName, "identityToken": identityToken @@ -52,7 +52,7 @@ public class DefaultLoginRepository: LoginRepository { let components = URLComponents(string: location) { let items = components.queryItems ?? [] let accessToken = items.first(where: { $0.name == "accessToken" })?.value - single(.success(LoginVO(accessToken: accessToken))) + single(.success(GoogleLoginVO(accessToken: accessToken))) } else { let error = NSError(domain: "DefaultLoginRepository", code: -1, diff --git a/Projects/Data/Sources/Repository/SignRepository.swift b/Projects/Data/Sources/Repository/SignRepository.swift index 123bb61..cb3844c 100644 --- a/Projects/Data/Sources/Repository/SignRepository.swift +++ b/Projects/Data/Sources/Repository/SignRepository.swift @@ -13,6 +13,17 @@ public class DefaultSignRepository: SignRepository { public init() { } + public func postSignIn(email: String, password: String) -> Single { + let params = ["email": email, + "password": password] + return request(endpoint: "/api/auth/sign-in", + parameters: params, + responseType: DefaultDTO.self) + .map { dto in + return dto.getMessage() + } + } + public func postEmail(email: String) -> Single { let params = ["email": email] return request(endpoint: "/api/auth/email", @@ -24,7 +35,8 @@ public class DefaultSignRepository: SignRepository { } public func postConfirm(email: String, code: String) -> Single { - let params = ["email": email, "code": code] + let params = ["email": email, + "code": code] return request(endpoint: "/api/auth/email/confirm", parameters: params, responseType: DefaultDTO.self) @@ -34,7 +46,9 @@ public class DefaultSignRepository: SignRepository { } public func postSignUp(username: String, email: String, password: String) -> Single { - let params = ["username": username, "email": email, "password": password] + let params = ["username": username, + "email": email, + "password": password] return request(endpoint: "/api/auth/sign-up", parameters: params, responseType: DefaultDTO.self) diff --git a/Projects/Domain/Sources/RepositoryProtocol/LoginRepository.swift b/Projects/Domain/Sources/RepositoryProtocol/LoginRepository.swift index 34607d1..1a7560a 100644 --- a/Projects/Domain/Sources/RepositoryProtocol/LoginRepository.swift +++ b/Projects/Domain/Sources/RepositoryProtocol/LoginRepository.swift @@ -8,6 +8,6 @@ import RxSwift public protocol LoginRepository { - func postGoogleLogin() -> Single - func postAppleLogin(userName: String?, identityToken: String) -> Single + func postGoogleLogin() -> Single + func postAppleLogin(userName: String?, identityToken: String) -> Single } diff --git a/Projects/Domain/Sources/RepositoryProtocol/SignRepository.swift b/Projects/Domain/Sources/RepositoryProtocol/SignRepository.swift index 8f231b5..9d2a920 100644 --- a/Projects/Domain/Sources/RepositoryProtocol/SignRepository.swift +++ b/Projects/Domain/Sources/RepositoryProtocol/SignRepository.swift @@ -8,6 +8,7 @@ import RxSwift public protocol SignRepository { + func postSignIn(email: String, password: String) -> Single func postEmail(email: String) -> Single func postConfirm(email: String, code: String) -> Single func postSignUp(username: String, email: String, password: String) -> Single diff --git a/Projects/Domain/Sources/UseCase/Login/LoginUseCase.swift b/Projects/Domain/Sources/UseCase/Login/LoginUseCase.swift index 77625bf..cde1ec8 100644 --- a/Projects/Domain/Sources/UseCase/Login/LoginUseCase.swift +++ b/Projects/Domain/Sources/UseCase/Login/LoginUseCase.swift @@ -8,8 +8,8 @@ import RxSwift public protocol LoginUseCase { - func postGoogleLogin() -> Single - func postAppleLogin(userName: String?, identityToken: String) -> Single + func postGoogleLogin() -> Single + func postAppleLogin(userName: String?, identityToken: String) -> Single } public final class DefaultLoginUseCase: LoginUseCase { @@ -19,11 +19,11 @@ public final class DefaultLoginUseCase: LoginUseCase { self.repository = repository } - public func postGoogleLogin() -> Single { + public func postGoogleLogin() -> Single { return repository.postGoogleLogin() } - public func postAppleLogin(userName: String?, identityToken: String) -> Single { + public func postAppleLogin(userName: String?, identityToken: String) -> Single { return repository.postAppleLogin(userName: userName, identityToken: identityToken) } } diff --git a/Projects/Domain/Sources/UseCase/Login/SignUseCase.swift b/Projects/Domain/Sources/UseCase/Login/SignUseCase.swift index d47e6a2..027cc54 100644 --- a/Projects/Domain/Sources/UseCase/Login/SignUseCase.swift +++ b/Projects/Domain/Sources/UseCase/Login/SignUseCase.swift @@ -8,6 +8,7 @@ import RxSwift public protocol SignUseCase { + func postSignIn(email: String, password: String) -> Single func postEmail(email: String) -> Single func postConfirm(email: String, code: String) -> Single func postSignUp(username: String, email: String, password: String) -> Single @@ -20,6 +21,10 @@ public final class DefaultSignUseCase: SignUseCase { self.repository = repository } + public func postSignIn(email: String, password: String) -> Single { + return repository.postSignIn(email: email, password: password) + } + public func postEmail(email: String) -> Single { return repository.postEmail(email: email) } diff --git a/Projects/Domain/Sources/VO/LoginVO.swift b/Projects/Domain/Sources/VO/LoginVO.swift index 6853246..3a042d1 100644 --- a/Projects/Domain/Sources/VO/LoginVO.swift +++ b/Projects/Domain/Sources/VO/LoginVO.swift @@ -5,16 +5,19 @@ // Created by 박지윤 on 7/16/25. // -//public struct LoginVO { -// public let list: [CourseVO] -// -// public init(list: [CourseVO]) { -// self.list = list -// } -//} - public struct LoginVO { public let accessToken: String? + public let refreshToken: String? + + public init(accessToken: String?, + refreshToken: String?) { + self.accessToken = accessToken + self.refreshToken = refreshToken + } +} + +public struct GoogleLoginVO { + public let accessToken: String? public init(accessToken: String?) { self.accessToken = accessToken diff --git a/Projects/Login/Sources/View/SignInViewController.swift b/Projects/Login/Sources/View/SignInViewController.swift index e6c5871..b617380 100644 --- a/Projects/Login/Sources/View/SignInViewController.swift +++ b/Projects/Login/Sources/View/SignInViewController.swift @@ -32,7 +32,6 @@ public class SignInViewController: BaseViewController { public override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) -// self.navigationController?.setNavigationBarHidden(, animated: false) } public override func viewDidLoad() { @@ -42,6 +41,17 @@ public class SignInViewController: BaseViewController { } private func bindActions() { + signInView.signInTapped + .bind { [weak self] in + guard let self = self else { return } + + let email = self.signInView.idTextField.currentText() + let password = self.signInView.passwordTextField.currentText() + + self.postSignIn(email: email, password: password) + } + .disposed(by: disposeBag) + signInView.signUpTapped .bind { [weak self] in self?.presentSignUp() @@ -49,10 +59,13 @@ public class SignInViewController: BaseViewController { .disposed(by: disposeBag) } + private func postSignIn(email: String, password: String) { + self.viewModel.postSignIn(email: email, + password: password) + } + private func presentSignUp() { onPresentSignUp?() -// let signUpViewController = SignUpViewController(signViewModel: viewModel) -// self.navigationController?.pushViewController(signUpViewController, animated: true) } private func bindTransition() { diff --git a/Projects/Login/Sources/ViewModel/SignViewModel.swift b/Projects/Login/Sources/ViewModel/SignViewModel.swift index 4c8cf55..e7e8d8b 100644 --- a/Projects/Login/Sources/ViewModel/SignViewModel.swift +++ b/Projects/Login/Sources/ViewModel/SignViewModel.swift @@ -29,6 +29,16 @@ public class SignViewModel: SignViewModelProtocol { self.signUseCase = signUseCase } + func postSignIn(email: String, password: String) { + signUseCase.postSignIn(email: email, password: password) + .subscribe(onSuccess: { [weak self] response in + print("로그인 성공: \(response.message)") + }, onFailure: { error in + print("로그인 실패: \(error)") + }) + .disposed(by: disposeBag) + } + func postEmail(email: String) { signUseCase.postEmail(email: email) .subscribe(onSuccess: { [weak self] response in From 1d4aaeffb5254e74c5c1e60562dc4626b10992ec Mon Sep 17 00:00:00 2001 From: Bibi-urssu Date: Sun, 7 Sep 2025 22:44:29 +0900 Subject: [PATCH 2/4] =?UTF-8?q?fix:=20LoginDTO=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Projects/Data/Sources/DTO/LoginDTO.swift | 11 +++++++++-- Projects/Data/Sources/Repository/SignRepository.swift | 4 ++-- .../Sources/RepositoryProtocol/SignRepository.swift | 2 +- .../Domain/Sources/UseCase/Login/SignUseCase.swift | 4 ++-- Projects/Login/Sources/ViewModel/SignViewModel.swift | 3 ++- 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/Projects/Data/Sources/DTO/LoginDTO.swift b/Projects/Data/Sources/DTO/LoginDTO.swift index d92df1c..8904d3a 100644 --- a/Projects/Data/Sources/DTO/LoginDTO.swift +++ b/Projects/Data/Sources/DTO/LoginDTO.swift @@ -9,14 +9,21 @@ import Foundation import Domain public struct LoginDTO: Decodable { + public let is_success: Bool + public let code: String + public let message: String + public let data: LoginDataDTO +} + +public struct LoginDataDTO: Decodable { public let accessToken: String public let refreshToken: String } extension LoginDTO { func getMessage() -> LoginVO { - return .init(accessToken: accessToken, - refreshToken: refreshToken) + return .init(accessToken: data.accessToken, + refreshToken: data.refreshToken) } } diff --git a/Projects/Data/Sources/Repository/SignRepository.swift b/Projects/Data/Sources/Repository/SignRepository.swift index cb3844c..d54b8b2 100644 --- a/Projects/Data/Sources/Repository/SignRepository.swift +++ b/Projects/Data/Sources/Repository/SignRepository.swift @@ -13,12 +13,12 @@ public class DefaultSignRepository: SignRepository { public init() { } - public func postSignIn(email: String, password: String) -> Single { + public func postSignIn(email: String, password: String) -> Single { let params = ["email": email, "password": password] return request(endpoint: "/api/auth/sign-in", parameters: params, - responseType: DefaultDTO.self) + responseType: LoginDTO.self) .map { dto in return dto.getMessage() } diff --git a/Projects/Domain/Sources/RepositoryProtocol/SignRepository.swift b/Projects/Domain/Sources/RepositoryProtocol/SignRepository.swift index 9d2a920..4eda6b7 100644 --- a/Projects/Domain/Sources/RepositoryProtocol/SignRepository.swift +++ b/Projects/Domain/Sources/RepositoryProtocol/SignRepository.swift @@ -8,7 +8,7 @@ import RxSwift public protocol SignRepository { - func postSignIn(email: String, password: String) -> Single + func postSignIn(email: String, password: String) -> Single func postEmail(email: String) -> Single func postConfirm(email: String, code: String) -> Single func postSignUp(username: String, email: String, password: String) -> Single diff --git a/Projects/Domain/Sources/UseCase/Login/SignUseCase.swift b/Projects/Domain/Sources/UseCase/Login/SignUseCase.swift index 027cc54..cf44439 100644 --- a/Projects/Domain/Sources/UseCase/Login/SignUseCase.swift +++ b/Projects/Domain/Sources/UseCase/Login/SignUseCase.swift @@ -8,7 +8,7 @@ import RxSwift public protocol SignUseCase { - func postSignIn(email: String, password: String) -> Single + func postSignIn(email: String, password: String) -> Single func postEmail(email: String) -> Single func postConfirm(email: String, code: String) -> Single func postSignUp(username: String, email: String, password: String) -> Single @@ -21,7 +21,7 @@ public final class DefaultSignUseCase: SignUseCase { self.repository = repository } - public func postSignIn(email: String, password: String) -> Single { + public func postSignIn(email: String, password: String) -> Single { return repository.postSignIn(email: email, password: password) } diff --git a/Projects/Login/Sources/ViewModel/SignViewModel.swift b/Projects/Login/Sources/ViewModel/SignViewModel.swift index e7e8d8b..bab088c 100644 --- a/Projects/Login/Sources/ViewModel/SignViewModel.swift +++ b/Projects/Login/Sources/ViewModel/SignViewModel.swift @@ -10,6 +10,7 @@ import RxSwift import RxRelay protocol SignViewModelProtocol { + func postSignIn(email: String, password: String) func postEmail(email: String) func postConfirm(email: String, code: String) func postSignUp(username: String, email: String, password: String) @@ -32,7 +33,7 @@ public class SignViewModel: SignViewModelProtocol { func postSignIn(email: String, password: String) { signUseCase.postSignIn(email: email, password: password) .subscribe(onSuccess: { [weak self] response in - print("로그인 성공: \(response.message)") + print("로그인 성공: \(response)") }, onFailure: { error in print("로그인 실패: \(error)") }) From 880db2fe315fce61eee883ea219ee36f009a1b06 Mon Sep 17 00:00:00 2001 From: Bibi-urssu Date: Sun, 7 Sep 2025 23:11:04 +0900 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20Login=20=EC=84=B1=EA=B3=B5=20?= =?UTF-8?q?=ED=9B=84=20HomeView=EB=A1=9C=20=ED=99=94=EB=A9=B4=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/Coordinator/AppCoordinator.swift | 12 ++++++++++++ .../Login/Sources/View/SignInViewController.swift | 6 ++++++ Projects/Login/Sources/ViewModel/SignViewModel.swift | 4 ++++ 3 files changed, 22 insertions(+) diff --git a/Projects/LearnMate/Sources/Coordinator/AppCoordinator.swift b/Projects/LearnMate/Sources/Coordinator/AppCoordinator.swift index f92d587..1e04d7c 100644 --- a/Projects/LearnMate/Sources/Coordinator/AppCoordinator.swift +++ b/Projects/LearnMate/Sources/Coordinator/AppCoordinator.swift @@ -15,6 +15,7 @@ protocol AppCoordinator: Coordinator { func showTabbarFlow() func setTabBarCoordinator() func getChildCoordinator(_ type: CoordinatorType) -> Coordinator? + func showHomeAfterLogin() } final class DefaultAppCoordinator: AppCoordinator{ @@ -44,6 +45,10 @@ final class DefaultAppCoordinator: AppCoordinator{ let signUpViewController = self.dependency.injector.resolve(SignUpViewController.self) self.navigationController.pushViewController(signUpViewController, animated: true) } + signInViewController.onLoginSuccess = { [weak self] in + guard let self else { return } + self.showHomeAfterLogin() + } self.navigationController.pushViewController(signInViewController, animated: true) } self.navigationController.pushViewController(loginViewController, animated: true) @@ -59,6 +64,13 @@ final class DefaultAppCoordinator: AppCoordinator{ tabBarCoordinator.start() } + /// 로그인 성공 후 홈으로 이동 + func showHomeAfterLogin() { + // 로그인 관련 뷰컨트롤러들을 모두 제거하고 탭바로 이동 + navigationController.viewControllers.removeAll() + showTabbarFlow() + } + /// 탭바 컨트롤러 세팅, 자식 코디네이터로 등록 func setTabBarCoordinator() { let dependency = DefaultTabBarController.Dependency.init( diff --git a/Projects/Login/Sources/View/SignInViewController.swift b/Projects/Login/Sources/View/SignInViewController.swift index b617380..871bf97 100644 --- a/Projects/Login/Sources/View/SignInViewController.swift +++ b/Projects/Login/Sources/View/SignInViewController.swift @@ -20,6 +20,7 @@ public class SignInViewController: BaseViewController { let signInView = SignInView() public var onPresentSignUp: (() -> Void)? + public var onLoginSuccess: (() -> Void)? public init(signViewModel: SignViewModel) { self.viewModel = signViewModel @@ -69,6 +70,11 @@ public class SignInViewController: BaseViewController { } private func bindTransition() { + viewModel.onSignInSuccess = { [weak self] in + DispatchQueue.main.async { + self?.onLoginSuccess?() + } + } } public override func setupViewProperty() { diff --git a/Projects/Login/Sources/ViewModel/SignViewModel.swift b/Projects/Login/Sources/ViewModel/SignViewModel.swift index bab088c..2c6316a 100644 --- a/Projects/Login/Sources/ViewModel/SignViewModel.swift +++ b/Projects/Login/Sources/ViewModel/SignViewModel.swift @@ -24,6 +24,7 @@ public class SignViewModel: SignViewModelProtocol { public var onEmailSuccess: (() -> Void)? public var onConfirmSuccess: (() -> Void)? public var onConfirmFailure: (() -> Void)? + public var onSignInSuccess: (() -> Void)? public let emailVerified = BehaviorRelay(value: false) public init(signUseCase: SignUseCase) { @@ -33,7 +34,10 @@ public class SignViewModel: SignViewModelProtocol { func postSignIn(email: String, password: String) { signUseCase.postSignIn(email: email, password: password) .subscribe(onSuccess: { [weak self] response in + guard let self = self else { return } print("로그인 성공: \(response)") + + self.onSignInSuccess?() }, onFailure: { error in print("로그인 실패: \(error)") }) From 83d39c0696fce38c98ed79b6b1158623b1cf3831 Mon Sep 17 00:00:00 2001 From: Bibi-urssu Date: Sun, 7 Sep 2025 23:11:25 +0900 Subject: [PATCH 4/4] =?UTF-8?q?feat:=20Token=20=EC=A0=80=EC=9E=A5=20?= =?UTF-8?q?=EB=B0=8F=20=EA=B4=80=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/Repository/TokenRepository.swift | 23 +++++++++++++++---- .../RepositoryProtocol/TokenRepository.swift | 5 +++- .../LearnMate/Sources/DI/LoginAssembly.swift | 3 ++- .../Sources/ViewModel/SignViewModel.swift | 13 ++++++++++- 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/Projects/Data/Sources/Repository/TokenRepository.swift b/Projects/Data/Sources/Repository/TokenRepository.swift index a071d9f..59438cd 100644 --- a/Projects/Data/Sources/Repository/TokenRepository.swift +++ b/Projects/Data/Sources/Repository/TokenRepository.swift @@ -10,23 +10,38 @@ import Foundation public class DefaultTokenRepository: TokenRepository { private let userDefaults = UserDefaults.standard - private let accessTokenKey = "accessToken" + private let accessToken = "accessToken" + private let refreshToken = "refreshToken" public init() { // Initialization if needed } public func saveAccessToken(_ token: String) { - userDefaults.set(token, forKey: accessTokenKey) + userDefaults.set(token, forKey: accessToken) print("✅ Access Token saved: \(token)") } public func getAccessToken() -> String? { - return userDefaults.string(forKey: accessTokenKey) + return userDefaults.string(forKey: accessToken) } public func clearAccessToken() { - userDefaults.removeObject(forKey: accessTokenKey) + userDefaults.removeObject(forKey: accessToken) print("🗑️ Access Token cleared") } + + public func saveRefreshToken(token: String) { + userDefaults.set(token, forKey: refreshToken) + print("✅ Refresh Token saved: \(token)") + } + + public func getRefreshToken() -> String? { + return userDefaults.string(forKey: refreshToken) + } + + public func clearRefreshToken() { + userDefaults.removeObject(forKey: refreshToken) + print("🗑️ Refresh Token cleared") + } } diff --git a/Projects/Domain/Sources/RepositoryProtocol/TokenRepository.swift b/Projects/Domain/Sources/RepositoryProtocol/TokenRepository.swift index a80d27b..19a27af 100644 --- a/Projects/Domain/Sources/RepositoryProtocol/TokenRepository.swift +++ b/Projects/Domain/Sources/RepositoryProtocol/TokenRepository.swift @@ -8,7 +8,10 @@ import RxSwift public protocol TokenRepository { - func saveAccessToken(_ token: String) + func saveAccessToken(token: String) func getAccessToken() -> String? func clearAccessToken() + func saveRefreshToken(token: String) + func getRefreshToken() -> String? + func clearRefreshToken() } diff --git a/Projects/LearnMate/Sources/DI/LoginAssembly.swift b/Projects/LearnMate/Sources/DI/LoginAssembly.swift index f3981cc..e09a32d 100644 --- a/Projects/LearnMate/Sources/DI/LoginAssembly.swift +++ b/Projects/LearnMate/Sources/DI/LoginAssembly.swift @@ -28,7 +28,8 @@ public struct LoginAssembly: Assembly { /// Sign DI 등록 container.register(SignViewModel.self) { resolver in let useCase = resolver.resolve(SignUseCase.self)! - return SignViewModel(signUseCase: useCase) + let tokenRepository = resolver.resolve(TokenRepository.self)! + return SignViewModel(signUseCase: useCase, tokenRepository: tokenRepository) } container.register(SignInViewController.self) { resolver in diff --git a/Projects/Login/Sources/ViewModel/SignViewModel.swift b/Projects/Login/Sources/ViewModel/SignViewModel.swift index 2c6316a..35a4f59 100644 --- a/Projects/Login/Sources/ViewModel/SignViewModel.swift +++ b/Projects/Login/Sources/ViewModel/SignViewModel.swift @@ -19,6 +19,7 @@ protocol SignViewModelProtocol { public class SignViewModel: SignViewModelProtocol { private let disposeBag = DisposeBag() private let signUseCase: SignUseCase + private let tokenRepository: TokenRepository public weak var signInViewCoordinator: SignInCoordinator? public weak var signUpViewCoordinator: SignUpCoordinator? public var onEmailSuccess: (() -> Void)? @@ -27,8 +28,9 @@ public class SignViewModel: SignViewModelProtocol { public var onSignInSuccess: (() -> Void)? public let emailVerified = BehaviorRelay(value: false) - public init(signUseCase: SignUseCase) { + public init(signUseCase: SignUseCase, tokenRepository: TokenRepository) { self.signUseCase = signUseCase + self.tokenRepository = tokenRepository } func postSignIn(email: String, password: String) { @@ -37,6 +39,15 @@ public class SignViewModel: SignViewModelProtocol { guard let self = self else { return } print("로그인 성공: \(response)") + if let accessToken = response.accessToken { + self.tokenRepository.saveAccessToken(token: accessToken) + print("🔑 토큰 저장 완료: \(accessToken)") + } + if let refreshToken = response.refreshToken { + self.tokenRepository.saveRefreshToken(token: refreshToken) + print("🔄 리프레시 토큰 저장 완료: \(refreshToken)") + } + self.onSignInSuccess?() }, onFailure: { error in print("로그인 실패: \(error)")