From f050a5207a0193232ff14031f013eeea4b0fa18e Mon Sep 17 00:00:00 2001 From: FreeDeveloper97 Date: Sun, 1 Sep 2024 18:55:13 +0900 Subject: [PATCH] =?UTF-8?q?feat=20#164:=20checkUsername=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20Repository,=20UseCase=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Project_Timer.xcodeproj/project.pbxproj | 28 +++++++++++++++++++ Project_Timer/Data/API/UserAPI.swift | 11 ++++---- .../Data/Repository/UserRepository.swift | 27 ++++++++++++++++++ .../Data/Response/CheckUsernameResponse.swift | 24 ++++++++++++++++ .../Domain/Entity/CheckUsernameInfo.swift | 14 ++++++++++ .../Domain/Entity/TTResponseDetailInfo.swift | 14 ++++++++++ .../User/GetUsernameNotExistUseCase.swift | 24 ++++++++++++++++ .../Present/Setting/Main/SettingVM.swift | 8 +++--- .../Signup/Email/SignupEmailModel.swift | 1 + 9 files changed, 141 insertions(+), 10 deletions(-) create mode 100644 Project_Timer/Data/Repository/UserRepository.swift create mode 100644 Project_Timer/Data/Response/CheckUsernameResponse.swift create mode 100644 Project_Timer/Domain/Entity/CheckUsernameInfo.swift create mode 100644 Project_Timer/Domain/Entity/TTResponseDetailInfo.swift create mode 100644 Project_Timer/Domain/UseCase/User/GetUsernameNotExistUseCase.swift diff --git a/Project_Timer.xcodeproj/project.pbxproj b/Project_Timer.xcodeproj/project.pbxproj index 6d2923e7..7e1b41be 100644 --- a/Project_Timer.xcodeproj/project.pbxproj +++ b/Project_Timer.xcodeproj/project.pbxproj @@ -87,6 +87,11 @@ 871AB69B2967C9C500AFED1C /* TimeTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 871AB69A2967C9C500AFED1C /* TimeTableView.swift */; }; 871AB69D2967C9D100AFED1C /* TimeTableVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 871AB69C2967C9D100AFED1C /* TimeTableVM.swift */; }; 871BC8C82C8468CE0092DFA7 /* UserAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 871BC8C72C8468CE0092DFA7 /* UserAPI.swift */; }; + 871BC8CB2C846D890092DFA7 /* GetUsernameNotExistUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 871BC8CA2C846D890092DFA7 /* GetUsernameNotExistUseCase.swift */; }; + 871BC8CD2C846DCF0092DFA7 /* UserRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 871BC8CC2C846DCF0092DFA7 /* UserRepository.swift */; }; + 871BC8CF2C846EC00092DFA7 /* CheckUsernameResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 871BC8CE2C846EC00092DFA7 /* CheckUsernameResponse.swift */; }; + 871BC8D12C84701B0092DFA7 /* TTResponseDetailInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 871BC8D02C84701B0092DFA7 /* TTResponseDetailInfo.swift */; }; + 871BC8D32C84703C0092DFA7 /* CheckUsernameInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 871BC8D22C84703C0092DFA7 /* CheckUsernameInfo.swift */; }; 871C1A0328519CC200BDAE02 /* SettingDevInfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 871C1A0228519CC200BDAE02 /* SettingDevInfoCell.swift */; }; 871DC0F42BC27E620024DA3B /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 871DC0F32BC27E620024DA3B /* GoogleService-Info.plist */; }; 871DC0F52BC280D60024DA3B /* Infos.swift in Sources */ = {isa = PBXBuildFile; fileRef = 876E27752AC1CD2A0054250D /* Infos.swift */; }; @@ -508,6 +513,11 @@ 871AB69A2967C9C500AFED1C /* TimeTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeTableView.swift; sourceTree = ""; }; 871AB69C2967C9D100AFED1C /* TimeTableVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeTableVM.swift; sourceTree = ""; }; 871BC8C72C8468CE0092DFA7 /* UserAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAPI.swift; sourceTree = ""; }; + 871BC8CA2C846D890092DFA7 /* GetUsernameNotExistUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetUsernameNotExistUseCase.swift; sourceTree = ""; }; + 871BC8CC2C846DCF0092DFA7 /* UserRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserRepository.swift; sourceTree = ""; }; + 871BC8CE2C846EC00092DFA7 /* CheckUsernameResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckUsernameResponse.swift; sourceTree = ""; }; + 871BC8D02C84701B0092DFA7 /* TTResponseDetailInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TTResponseDetailInfo.swift; sourceTree = ""; }; + 871BC8D22C84703C0092DFA7 /* CheckUsernameInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckUsernameInfo.swift; sourceTree = ""; }; 871C1A0228519CC200BDAE02 /* SettingDevInfoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingDevInfoCell.swift; sourceTree = ""; }; 871DC0F32BC27E620024DA3B /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 871EDFED288AF6E900B428A6 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -992,6 +1002,14 @@ path = ViewModel; sourceTree = ""; }; + 871BC8C92C846D6E0092DFA7 /* User */ = { + isa = PBXGroup; + children = ( + 871BC8CA2C846D890092DFA7 /* GetUsernameNotExistUseCase.swift */, + ); + path = User; + sourceTree = ""; + }; 872210532C300922003B97AD /* Firebase */ = { isa = PBXGroup; children = ( @@ -1205,6 +1223,8 @@ 872210462C2FF676003B97AD /* SurveyInfo.swift */, 872210482C2FF6AF003B97AD /* FunctionInfo.swift */, 8722104A2C2FF6E7003B97AD /* UpdateHistoryInfo.swift */, + 871BC8D02C84701B0092DFA7 /* TTResponseDetailInfo.swift */, + 871BC8D22C84703C0092DFA7 /* CheckUsernameInfo.swift */, ); path = Entity; sourceTree = ""; @@ -1694,6 +1714,7 @@ 875C98C62871BB26008F7ADD /* YoutubeLinkResponse.swift */, 87B90B3E2BF4BC6D00D6886E /* TTErrorResponse.swift */, 8722104C2C2FFA66003B97AD /* TTResponse.swift */, + 871BC8CE2C846EC00092DFA7 /* CheckUsernameResponse.swift */, ); path = Response; sourceTree = ""; @@ -1916,6 +1937,7 @@ 87F778E02B196EDF00909511 /* UseCase */ = { isa = PBXGroup; children = ( + 871BC8C92C846D6E0092DFA7 /* User */, 874A9DF42C6837BF006D2E19 /* Notification */, 872210532C300922003B97AD /* Firebase */, 877BDCDF2C390BAE00A50231 /* Auth */, @@ -1934,6 +1956,7 @@ 874B542B2C1592460062D0AC /* DailysRepository.swift */, 874B542D2C1595A00062D0AC /* RecordTimesRepository.swift */, 872210412C2FEE83003B97AD /* SyncLogRepository.swift */, + 871BC8CC2C846DCF0092DFA7 /* UserRepository.swift */, ); path = Repository; sourceTree = ""; @@ -2273,6 +2296,7 @@ 877911BA2A1891B100F0A713 /* SettingSwitchListVM.swift in Sources */, 875FAE372B1C74AD008F19D2 /* FirebaseBooleanValue.swift in Sources */, 87BEBEE9281C17000095CD29 /* RecordsManager.swift in Sources */, + 871BC8D12C84701B0092DFA7 /* TTResponseDetailInfo.swift in Sources */, 87FB8D1D2B3C5F4D00EA5693 /* NotificationUseCaseInterface.swift in Sources */, 87A48BCD27DF182400F46D0F /* SubjectCell.swift in Sources */, 04172E982885453F00F962F2 /* MotionDetector.swift in Sources */, @@ -2292,6 +2316,7 @@ 871616A02C3A605600C4EF25 /* PostRecordTimeUseCase.swift in Sources */, 8791081F28387537005D7B10 /* NetworkURL.swift in Sources */, 87D83E852B285D4D003C40AE /* SettingLanguageVC.swift in Sources */, + 871BC8CD2C846DCF0092DFA7 /* UserRepository.swift in Sources */, 873C197628D041DE00E02ADC /* DailyView.swift in Sources */, 87D4DCCF2BA5492700BB5AAB /* SimpleResponse.swift in Sources */, 87B90B3C2BF4B13D00D6886E /* AppVersionResponse.swift in Sources */, @@ -2374,6 +2399,7 @@ 87F1093B284C589A002E31EA /* SettingFunctionsListVM.swift in Sources */, 8708006F2B2CA92C00830B39 /* DailyResponse.swift in Sources */, 8788997C2894F00000B7F378 /* LogWeekVM.swift in Sources */, + 871BC8D32C84703C0092DFA7 /* CheckUsernameInfo.swift in Sources */, 8761BDCA2BCFEA7A00E9281A /* AuthAPI.swift in Sources */, 87EFD6812AC115DB00C422B1 /* SigninSignupVC.swift in Sources */, 873C197828D044CC00E02ADC /* DailyVM.swift in Sources */, @@ -2432,6 +2458,7 @@ 879E849C29C83D5100D65F48 /* RoundedShape.swift in Sources */, 87199F582883F2E00017D01A /* TimelineVM.swift in Sources */, 8761BDC02BCFE52E00E9281A /* FirebaseAPI.swift in Sources */, + 871BC8CF2C846EC00092DFA7 /* CheckUsernameResponse.swift in Sources */, 877036CA29CD7B3B0078A30C /* TaskManager.swift in Sources */, 8761BDCC2BCFEC8500E9281A /* DailysAPI.swift in Sources */, 878DA8212B0C62E1001E924E /* SignupNicknameView.swift in Sources */, @@ -2502,6 +2529,7 @@ 8706C3302AEF881500F7C842 /* TTSignupTextFieldWarning.swift in Sources */, 87F10932284C4367002E31EA /* SurveyCell.swift in Sources */, 87D4DCBE2BA51EEA00BB5AAB /* ResetPasswordVC.swift in Sources */, + 871BC8CB2C846D890092DFA7 /* GetUsernameNotExistUseCase.swift in Sources */, 879E849F29C8400700D65F48 /* TimeLabelData.swift in Sources */, 04FA75D3286EE4D900BAE2B2 /* Color+Extension.swift in Sources */, 870800892B2D59EB00830B39 /* SyncLogResponse.swift in Sources */, diff --git a/Project_Timer/Data/API/UserAPI.swift b/Project_Timer/Data/API/UserAPI.swift index 9dd9564c..c9f7cbbc 100644 --- a/Project_Timer/Data/API/UserAPI.swift +++ b/Project_Timer/Data/API/UserAPI.swift @@ -11,7 +11,7 @@ import Moya enum UserAPI { /// 존재하는 Username인지 확인해요. - case checkUsername(username: String) + case checkUsername(request: CheckUsernameRequest) } extension UserAPI: TargetType { @@ -35,12 +35,11 @@ extension UserAPI: TargetType { var task: Moya.Task { switch self { - case .checkUsername(let username): + case .checkUsername(let request): return .requestParameters( - parameters: [ - "username": username - ], - encoding: URLEncoding.queryString) + parameters: Self.parameters(from: request), + encoding: URLEncoding.queryString + ) } } diff --git a/Project_Timer/Data/Repository/UserRepository.swift b/Project_Timer/Data/Repository/UserRepository.swift new file mode 100644 index 00000000..41669012 --- /dev/null +++ b/Project_Timer/Data/Repository/UserRepository.swift @@ -0,0 +1,27 @@ +// +// UserRepository.swift +// Project_Timer +// +// Created by Kang Minsang on 2024/09/01. +// Copyright © 2024 FDEE. All rights reserved. +// + +import Foundation +import Moya +import Combine +import CombineMoya + +final class UserRepository { + private let api: TTProvider + + init(api: TTProvider) { + self.api = api + } + + func checkUsername(request: CheckUsernameRequest) -> AnyPublisher { + return self.api.request(.checkUsername(request: request)) + .map(CheckUsernameResponse.self) + .map { $0.toDomain() } + .catchDecodeError() + } +} diff --git a/Project_Timer/Data/Response/CheckUsernameResponse.swift b/Project_Timer/Data/Response/CheckUsernameResponse.swift new file mode 100644 index 00000000..99249347 --- /dev/null +++ b/Project_Timer/Data/Response/CheckUsernameResponse.swift @@ -0,0 +1,24 @@ +// +// CheckUsernameResponse.swift +// Project_Timer +// +// Created by Kang Minsang on 2024/09/01. +// Copyright © 2024 FDEE. All rights reserved. +// + +import Foundation + +struct CheckUsernameResponse: Decodable { + let code: String + let message: String + let isPresent: Bool +} + +extension CheckUsernameResponse { + func toDomain() -> CheckUsernameInfo { + return .init( + detailInfo: .init(code: self.code, message: self.message), + isNotExist: !self.isPresent + ) + } +} diff --git a/Project_Timer/Domain/Entity/CheckUsernameInfo.swift b/Project_Timer/Domain/Entity/CheckUsernameInfo.swift new file mode 100644 index 00000000..d7fb32e1 --- /dev/null +++ b/Project_Timer/Domain/Entity/CheckUsernameInfo.swift @@ -0,0 +1,14 @@ +// +// CheckUsernameInfo.swift +// Project_Timer +// +// Created by Kang Minsang on 2024/09/01. +// Copyright © 2024 FDEE. All rights reserved. +// + +import Foundation + +struct CheckUsernameInfo { + let detailInfo: TTResponseDetailInfo + let isNotExist: Bool +} diff --git a/Project_Timer/Domain/Entity/TTResponseDetailInfo.swift b/Project_Timer/Domain/Entity/TTResponseDetailInfo.swift new file mode 100644 index 00000000..467bc208 --- /dev/null +++ b/Project_Timer/Domain/Entity/TTResponseDetailInfo.swift @@ -0,0 +1,14 @@ +// +// TTResponseDetailInfo.swift +// Project_Timer +// +// Created by Kang Minsang on 2024/09/01. +// Copyright © 2024 FDEE. All rights reserved. +// + +import Foundation + +struct TTResponseDetailInfo { + let code: String? + let message: String? +} diff --git a/Project_Timer/Domain/UseCase/User/GetUsernameNotExistUseCase.swift b/Project_Timer/Domain/UseCase/User/GetUsernameNotExistUseCase.swift new file mode 100644 index 00000000..b15ffb17 --- /dev/null +++ b/Project_Timer/Domain/UseCase/User/GetUsernameNotExistUseCase.swift @@ -0,0 +1,24 @@ +// +// GetUsernameNotExistUseCase.swift +// Project_Timer +// +// Created by Kang Minsang on 2024/09/01. +// Copyright © 2024 FDEE. All rights reserved. +// + +import Foundation +import Combine + +final class GetUsernameNotExistUseCase { + private let repository: UserRepository // TODO: 프로토콜로 수정 + + init(repository: UserRepository) { + self.repository = repository + } + + func execute(username: String) -> AnyPublisher { + return self.repository.checkUsername( + request: .init(username: username) + ) + } +} diff --git a/Project_Timer/Present/Setting/Main/SettingVM.swift b/Project_Timer/Present/Setting/Main/SettingVM.swift index c36d96ab..7a3d36cc 100644 --- a/Project_Timer/Present/Setting/Main/SettingVM.swift +++ b/Project_Timer/Present/Setting/Main/SettingVM.swift @@ -27,9 +27,9 @@ final class SettingVM { private func configureSections() { // MARK: Dev - if Infos.isDevMode { +// if Infos.isDevMode { self.sections.append(Localized.string(.Settings_Text_ProfileSection)) - } +// } self.sections.append(Localized.string(.Settings_Text_ServiceSection)) self.sections.append(Localized.string(.Settings_Text_SettingSection)) @@ -43,12 +43,12 @@ final class SettingVM { var cells: [[SettingCellInfo]] = [] // MARK: Dev - if Infos.isDevMode { +// if Infos.isDevMode { // Profile cells.append([ SettingCellInfo(title: Localized.string(.Settings_Button_SingInOption), subTitle: Localized.string(.Settings_Button_SingInOptionDesc), action: .modalFullscreen, destination: .signinSelect) ]) - } +// } // Service cells.append([ diff --git a/Project_Timer/Present/Signup/Email/SignupEmailModel.swift b/Project_Timer/Present/Signup/Email/SignupEmailModel.swift index 794ba9e8..09ce84f8 100644 --- a/Project_Timer/Present/Signup/Email/SignupEmailModel.swift +++ b/Project_Timer/Present/Signup/Email/SignupEmailModel.swift @@ -109,6 +109,7 @@ extension SignupEmailModel { validEmail = PredicateChecker.isValidEmail(email) // stage 변화 -> @FocusState 반영 if validEmail == true { + // API 요청 resetVerificationCode() } else { resetEmail()