From 8026f5b3caa12b8da6eca640e60cdc45588c9454 Mon Sep 17 00:00:00 2001 From: FreeDeveloper97 Date: Tue, 1 Oct 2024 22:53:21 +0900 Subject: [PATCH] =?UTF-8?q?feat=20#166:=20=EC=9D=B8=EC=A6=9D=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EA=B2=80=EC=A6=9D=20api=20=EB=8F=99=EC=9E=91=20?= =?UTF-8?q?=ED=99=95=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Project_Timer.xcodeproj/project.pbxproj | 4 ++ .../AuthV2/VerifyAuthCodeUseCase.swift | 22 ++++++++++ .../Signin/LoginSelect/SigninSelectView.swift | 4 +- .../Present/Signin/LoginView/SigninView.swift | 4 +- .../Signup/Email/SignupEmailModel.swift | 40 ++++++++++++------- .../Signup/Email/SignupEmailView.swift | 6 ++- 6 files changed, 62 insertions(+), 18 deletions(-) create mode 100644 Project_Timer/Domain/UseCase/AuthV2/VerifyAuthCodeUseCase.swift diff --git a/Project_Timer.xcodeproj/project.pbxproj b/Project_Timer.xcodeproj/project.pbxproj index 0eff7e16..10b071df 100644 --- a/Project_Timer.xcodeproj/project.pbxproj +++ b/Project_Timer.xcodeproj/project.pbxproj @@ -158,6 +158,7 @@ 874DCBE72CABEFB500CF9435 /* VerifyAuthCodeRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 874DCBE62CABEFB500CF9435 /* VerifyAuthCodeRequest.swift */; }; 874DCBE92CABF09100CF9435 /* VerifyAuthCodeInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 874DCBE82CABF09100CF9435 /* VerifyAuthCodeInfo.swift */; }; 874DCBEB2CABF0B700CF9435 /* VerifyAuthCodeResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 874DCBEA2CABF0B700CF9435 /* VerifyAuthCodeResponse.swift */; }; + 874DCBED2CAC0E7000CF9435 /* VerifyAuthCodeUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 874DCBEC2CAC0E7000CF9435 /* VerifyAuthCodeUseCase.swift */; }; 874F9C2B2ABFF51700675A86 /* SigninSelectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 874F9C2A2ABFF51700675A86 /* SigninSelectView.swift */; }; 874F9C2D2ABFF73400675A86 /* AppleSigninButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 874F9C2C2ABFF73400675A86 /* AppleSigninButton.swift */; }; 874F9C2F2ABFF7CF00675A86 /* GoogleSigninButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 874F9C2E2ABFF7CF00675A86 /* GoogleSigninButton.swift */; }; @@ -594,6 +595,7 @@ 874DCBE62CABEFB500CF9435 /* VerifyAuthCodeRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerifyAuthCodeRequest.swift; sourceTree = ""; }; 874DCBE82CABF09100CF9435 /* VerifyAuthCodeInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerifyAuthCodeInfo.swift; sourceTree = ""; }; 874DCBEA2CABF0B700CF9435 /* VerifyAuthCodeResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerifyAuthCodeResponse.swift; sourceTree = ""; }; + 874DCBEC2CAC0E7000CF9435 /* VerifyAuthCodeUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerifyAuthCodeUseCase.swift; sourceTree = ""; }; 874F9C2A2ABFF51700675A86 /* SigninSelectView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SigninSelectView.swift; sourceTree = ""; }; 874F9C2C2ABFF73400675A86 /* AppleSigninButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleSigninButton.swift; sourceTree = ""; }; 874F9C2E2ABFF7CF00675A86 /* GoogleSigninButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoogleSigninButton.swift; sourceTree = ""; }; @@ -1165,6 +1167,7 @@ isa = PBXGroup; children = ( 8736B74F2CA951EC006BD389 /* PostAuthCodeUseCase.swift */, + 874DCBEC2CAC0E7000CF9435 /* VerifyAuthCodeUseCase.swift */, ); path = AuthV2; sourceTree = ""; @@ -2437,6 +2440,7 @@ 8708006F2B2CA92C00830B39 /* DailyResponse.swift in Sources */, 8788997C2894F00000B7F378 /* LogWeekVM.swift in Sources */, 871BC8D32C84703C0092DFA7 /* CheckUsernameInfo.swift in Sources */, + 874DCBED2CAC0E7000CF9435 /* VerifyAuthCodeUseCase.swift in Sources */, 8761BDCA2BCFEA7A00E9281A /* AuthAPI.swift in Sources */, 87EFD6812AC115DB00C422B1 /* SigninSignupVC.swift in Sources */, 873C197828D044CC00E02ADC /* DailyVM.swift in Sources */, diff --git a/Project_Timer/Domain/UseCase/AuthV2/VerifyAuthCodeUseCase.swift b/Project_Timer/Domain/UseCase/AuthV2/VerifyAuthCodeUseCase.swift new file mode 100644 index 00000000..c3da75c4 --- /dev/null +++ b/Project_Timer/Domain/UseCase/AuthV2/VerifyAuthCodeUseCase.swift @@ -0,0 +1,22 @@ +// +// VerifyAuthCodeUseCase.swift +// Project_Timer +// +// Created by Kang Minsang on 2024/10/01. +// Copyright © 2024 FDEE. All rights reserved. +// + +import Foundation +import Combine + +final class VerifyAuthCodeUseCase { + private let repository: AuthV2Repository // TODO: 프로토콜로 수정 + + init(repository: AuthV2Repository) { + self.repository = repository + } + + func execute(request: VerifyAuthCodeRequest) -> AnyPublisher { + return self.repository.verifyAuthCode(request: request) + } +} diff --git a/Project_Timer/Present/Signin/LoginSelect/SigninSelectView.swift b/Project_Timer/Present/Signin/LoginSelect/SigninSelectView.swift index 4cfe406a..abc625d7 100644 --- a/Project_Timer/Present/Signin/LoginSelect/SigninSelectView.swift +++ b/Project_Timer/Present/Signin/LoginSelect/SigninSelectView.swift @@ -49,11 +49,13 @@ struct SigninSelectView: View { let authRepository = AuthV2Repository(api: authApi) let getUsernameNotExistUseCase = GetUsernameNotExistUseCase(repository: userRepository) let postAuthCodeUseCase = PostAuthCodeUseCase(repository: authRepository) + let verifyAuthCodeUseCase = VerifyAuthCodeUseCase(repository: authRepository) SignupEmailView( model: SignupEmailModel( infos: infos, getUsernameNotExistUseCase: getUsernameNotExistUseCase, - postAuthCodeUseCase: postAuthCodeUseCase + postAuthCodeUseCase: postAuthCodeUseCase, + verifyAuthCodeUseCase: verifyAuthCodeUseCase ) ) case .signin: diff --git a/Project_Timer/Present/Signin/LoginView/SigninView.swift b/Project_Timer/Present/Signin/LoginView/SigninView.swift index a91766b8..3691072c 100644 --- a/Project_Timer/Present/Signin/LoginView/SigninView.swift +++ b/Project_Timer/Present/Signin/LoginView/SigninView.swift @@ -48,11 +48,13 @@ struct SigninView: View { let authRepository = AuthV2Repository(api: authApi) let getUsernameNotExistUseCase = GetUsernameNotExistUseCase(repository: userRepository) let postAuthCodeUseCase = PostAuthCodeUseCase(repository: authRepository) + let verifyAuthCodeUseCase = VerifyAuthCodeUseCase(repository: authRepository) SignupEmailView( model: SignupEmailModel( infos: infos, getUsernameNotExistUseCase: getUsernameNotExistUseCase, - postAuthCodeUseCase: postAuthCodeUseCase + postAuthCodeUseCase: postAuthCodeUseCase, + verifyAuthCodeUseCase: verifyAuthCodeUseCase ) ) } diff --git a/Project_Timer/Present/Signup/Email/SignupEmailModel.swift b/Project_Timer/Present/Signup/Email/SignupEmailModel.swift index c14acf79..578b4c94 100644 --- a/Project_Timer/Present/Signup/Email/SignupEmailModel.swift +++ b/Project_Timer/Present/Signup/Email/SignupEmailModel.swift @@ -30,11 +30,15 @@ class SignupEmailModel: ObservableObject { enum Action { case resendAuthCode + case verifyAuthCode } + public func action(_ action: Action) { switch action { case .resendAuthCode: self.postAuthCode() + case .verifyAuthCode: + self.verifyAuthCode() } } @@ -77,16 +81,19 @@ class SignupEmailModel: ObservableObject { private let getUsernameNotExistUseCase: GetUsernameNotExistUseCase private let postAuthCodeUseCase: PostAuthCodeUseCase + private let verifyAuthCodeUseCase: VerifyAuthCodeUseCase private var cancellables = Set() init( infos: SignupInfosForEmail, getUsernameNotExistUseCase: GetUsernameNotExistUseCase, - postAuthCodeUseCase: PostAuthCodeUseCase + postAuthCodeUseCase: PostAuthCodeUseCase, + verifyAuthCodeUseCase: VerifyAuthCodeUseCase ) { self.infos = infos self.getUsernameNotExistUseCase = getUsernameNotExistUseCase self.postAuthCodeUseCase = postAuthCodeUseCase + self.verifyAuthCodeUseCase = verifyAuthCodeUseCase // vender email 정보를 기본값으로 설정 if let email = infos.venderInfo?.email { self.email = email @@ -191,12 +198,12 @@ extension SignupEmailModel { /// 인증코드 전송, 전송 시점 저장 및 authKey 수신 후 저장 private func postAuthCode() { - self.postAuthCodeTerminateDate = Calendar.current.date(byAdding: .minute, value: 1, to: Date()) + self.postAuthCodeTerminateDate = Calendar.current.date(byAdding: .minute, value: 5, to: Date()) self.postAuthCodeUseCase.execute(type: .signup(email: self.email)) .sink { [weak self] completion in guard case .failure(let networkError) = completion else { return } print("ERROR", #function) - self?.handleCheckEmailError(networkError) + // TODO: 인증코드 전송 실패시 핸들링 } receiveValue: { [weak self] postAuthCodeInfo in print("authKey: \(postAuthCodeInfo.authKey)") self?.authKey = postAuthCodeInfo.authKey @@ -209,7 +216,7 @@ extension SignupEmailModel { // 인증코드 유효시간 표시 timer 동작 func runTimer() { DispatchQueue.main.async { [weak self] in - self?.timer = Timer.scheduledTimer(withTimeInterval: 5, repeats: true, block: { [weak self] timer in + self?.timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { [weak self] timer in guard let postAuthCodeTerminateDate = self?.postAuthCodeTerminateDate else { return } let remainSeconds = Int(postAuthCodeTerminateDate.timeIntervalSinceNow) if remainSeconds <= 0 { @@ -222,16 +229,21 @@ extension SignupEmailModel { } // 인증코드 done 액션 - func checkVerificationCode() { - validVerificationCode = authCode.count > 7 - // stage 변화 -> @StateFocus 반영 - if validVerificationCode == true { - // verificationKey 수신 필요 - authCode = "abcd1234" - getVerificationSuccess = true - } else { - resetVerificationCode() - } + private func verifyAuthCode() { + guard let authKey = self.authKey else { return } + let request = VerifyAuthCodeRequest(authKey: authKey, authCode: self.authCode) + self.verifyAuthCodeUseCase.execute(request: request) + .sink { [weak self] completion in + guard case .failure(let networkError) = completion else { return } + print("ERROR", #function) + // TODO: 인증코드 검증 실패시 핸들링 + } receiveValue: { [weak self] verifyAuthCodeInfo in + print("authToken: \(verifyAuthCodeInfo.authToken)") + // TODO: authToken 전달 구현 + self?.validVerificationCode = true + self?.getVerificationSuccess = true + } + .store(in: &self.cancellables) } private func resetEmail() { diff --git a/Project_Timer/Present/Signup/Email/SignupEmailView.swift b/Project_Timer/Present/Signup/Email/SignupEmailView.swift index cce91e19..80b6a607 100644 --- a/Project_Timer/Present/Signup/Email/SignupEmailView.swift +++ b/Project_Timer/Present/Signup/Email/SignupEmailView.swift @@ -150,7 +150,7 @@ struct SignupEmailView: View { HStack(alignment: .center, spacing: 16) { TTSignupTextFieldView(type: .verificationCode, keyboardType: .alphabet, text: $model.authCode, focus: $focus) { - model.checkVerificationCode() + model.action(.verifyAuthCode) } .frame(maxWidth: .infinity) @@ -194,11 +194,13 @@ struct SignupEmailView_Previews: PreviewProvider { let authRepository = AuthV2Repository(api: authApi) let getUsernameNotExistUseCase = GetUsernameNotExistUseCase(repository: userRepository) let postAuthCodeUseCase = PostAuthCodeUseCase(repository: authRepository) + let verifyAuthCodeUseCase = VerifyAuthCodeUseCase(repository: authRepository) SignupEmailView( model: SignupEmailModel( infos: infos, getUsernameNotExistUseCase: getUsernameNotExistUseCase, - postAuthCodeUseCase: postAuthCodeUseCase + postAuthCodeUseCase: postAuthCodeUseCase, + verifyAuthCodeUseCase: verifyAuthCodeUseCase ) ).environmentObject(SigninSignupEnvironment()) }