Skip to content

Commit 725b3b4

Browse files
authored
Merge pull request #44 from YAPP-Github/TNT-158-trainerSignup
[TNT-158] postSingIn 구현 완료
2 parents e21c38f + af3a661 commit 725b3b4

29 files changed

+495
-30
lines changed

.gitignore

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,4 @@ Signing/
7777
master.key
7878

7979
# PList
80-
# => 전체 plist를 다 제외함.
81-
# **/*.plist
82-
# Support/*.plist
8380
GoogleService-Info.plist

TnT/.gitignore

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,4 @@ Signing/
7777
master.key
7878

7979
# PList
80-
# => 전체 plist를 다 제외함.
81-
# **/*.plist
82-
# Support/*.plist
8380
GoogleService-Info.plist

TnT/Projects/DIContainer/Sources/DIContainer.swift

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ import Data
1212

1313
// MARK: - Swift-Dependencies
1414
private enum UserUseCaseKey: DependencyKey {
15-
static let liveValue: UserUseCase = DefaultUserUseCase(userRepository: UserRepositoryImpl())
15+
static let liveValue: UserUseCase = DefaultUserUseCase(userRepostiory: UserRepositoryImpl())
16+
}
17+
18+
private enum UserUseCaseRepoKey: DependencyKey {
19+
static let liveValue: UserRepository = DefaultUserUseCase(userRepostiory: UserRepositoryImpl())
1620
}
1721

1822
private enum TraineeUseCaseKey: DependencyKey {
@@ -22,15 +26,29 @@ private enum TraineeUseCaseKey: DependencyKey {
2226
)
2327
}
2428

29+
private enum SocialUseCaseKey: DependencyKey {
30+
static let liveValue: SocialLoginUseCase = SocialLoginUseCase(socialLoginRepository: SocialLogInRepositoryImpl(loginManager: SNSLoginManager()))
31+
}
32+
2533
// MARK: - DependencyValues
2634
public extension DependencyValues {
2735
var userUseCase: UserUseCase {
2836
get { self[UserUseCaseKey.self] }
2937
set { self[UserUseCaseKey.self] = newValue }
3038
}
3139

40+
var userUseRepoCase: UserRepository {
41+
get { self[UserUseCaseRepoKey.self] }
42+
set { self[UserUseCaseRepoKey.self] = newValue }
43+
}
44+
3245
var traineeUseCase: TraineeUseCase {
3346
get { self[TraineeUseCaseKey.self] }
3447
set { self[TraineeUseCaseKey.self] = newValue }
3548
}
49+
50+
var socialLogInUseCase: SocialLoginUseCase {
51+
get { self[SocialUseCaseKey.self] }
52+
set { self[SocialUseCaseKey.self] = newValue }
53+
}
3654
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//
2+
// SocialLogInRepositoryImpl.swift
3+
// Data
4+
//
5+
// Created by 박서연 on 1/29/25.
6+
// Copyright © 2025 yapp25thTeamTnT. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import Dependencies
11+
12+
import Domain
13+
14+
public enum LoginError: Error {
15+
case invalidCredentials
16+
case networkFailure
17+
case kakaoError
18+
case appleError
19+
case unknown(message: String)
20+
}
21+
22+
public struct SocialLogInRepositoryImpl: SocialLoginRepository {
23+
24+
public let loginManager: SNSLoginManager
25+
26+
public init(loginManager: SNSLoginManager) {
27+
self.loginManager = loginManager
28+
}
29+
30+
public func appleLogin() async -> AppleLoginInfo? {
31+
let result = await loginManager.appleLogin()
32+
33+
return result
34+
}
35+
36+
public func kakaoLogin() async -> KakaoLoginInfo? {
37+
let result = await loginManager.kakaoLogin()
38+
return result
39+
}
40+
}

TnT/Projects/Data/Sources/Network/Service/User/UserRepositoryImpl.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import Domain
1313

1414
/// 사용자 관련 네트워크 요청을 처리하는 UserRepository 구현체
1515
public struct UserRepositoryImpl: UserRepository {
16-
1716
private let networkService: NetworkService = .shared
1817

1918
public init() {}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
//
2+
// PostSocailEntity.swift
3+
// Domain
4+
//
5+
// Created by 박서연 on 1/31/25.
6+
// Copyright © 2025 yapp25thTeamTnT. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
/// 소셜 로그인 요청 DTO
12+
public struct PostSocailEntity: Equatable {
13+
/// 소셜 로그인 타입 (KAKAO, APPLE)
14+
let socialType: String
15+
/// FCM 토큰
16+
let fcmToken: String
17+
/// 소셜 액세스 토큰
18+
let socialAccessToken: String?
19+
/// 애플 인가 코드 (Apple 로그인 시 필요)
20+
let authorizationCode: String?
21+
/// 애플 ID 토큰 (Apple 로그인 시 필요)
22+
let idToken: String?
23+
24+
public init(
25+
socialType: String,
26+
fcmToken: String,
27+
socialAccessToken: String?,
28+
authorizationCode: String?,
29+
idToken: String?
30+
) {
31+
self.socialType = socialType
32+
self.fcmToken = fcmToken
33+
self.socialAccessToken = socialAccessToken
34+
self.authorizationCode = authorizationCode
35+
self.idToken = idToken
36+
}
37+
}
38+
39+
/// 소셜 로그인 응답 DTO
40+
public struct PostSocialLoginResEntity: Equatable {
41+
/// 세션 ID
42+
public let sessionId: String?
43+
/// 소셜 로그인 ID
44+
public let socialId: String
45+
/// 소셜 이메일
46+
public let socialEmail: String
47+
/// 소셜 로그인 타입 (KAKAO, APPLE)
48+
public let socialType: String
49+
/// 가입 여부 (`true`: 이미 가입됨, `false`: 미가입)
50+
public let isSignUp: Bool
51+
}
52+
53+
/// 회원가입 요청 DTO
54+
public struct PostSignUpReqEntity {
55+
/// FCM 토큰
56+
let fcmToken: String
57+
/// 회원 타입 (trainer, trainee)
58+
let memberType: String
59+
/// 소셜 로그인 타입 (KAKAO, APPLE)
60+
let socialType: String
61+
/// 소셜 로그인 ID
62+
let socialId: String
63+
/// 소셜 로그인 이메일
64+
let socialEmail: String
65+
/// 서비스 이용 약관 동의 여부
66+
let serviceAgreement: Bool
67+
/// 개인정보 수집 동의 여부
68+
let collectionAgreement: Bool
69+
/// 광고성 알림 수신 동의 여부
70+
let advertisementAgreement: Bool
71+
/// 푸시 알림 수신 동의 여부
72+
let pushAgreement: Bool
73+
/// 회원 이름
74+
let name: String
75+
/// 생년월일 (yyyy-MM-dd)
76+
let birthday: String?
77+
/// 키 (cm)
78+
let height: Double?
79+
/// 몸무게 (kg, 소수점 1자리까지 가능)
80+
let weight: Double?
81+
/// 트레이너에게 전달할 주의사항
82+
let cautionNote: String?
83+
/// PT 목적 (체중 감량, 근력 향상 등)
84+
let goalContents: [String]?
85+
86+
public init(
87+
fcmToken: String,
88+
memberType: String,
89+
socialType: String,
90+
socialId: String,
91+
socialEmail: String,
92+
serviceAgreement: Bool,
93+
collectionAgreement: Bool,
94+
advertisementAgreement: Bool,
95+
pushAgreement: Bool,
96+
name: String,
97+
birthday: String?,
98+
height: Double?,
99+
weight: Double?,
100+
cautionNote: String?,
101+
goalContents: [String]?
102+
) {
103+
self.fcmToken = fcmToken
104+
self.memberType = memberType
105+
self.socialType = socialType
106+
self.socialId = socialId
107+
self.socialEmail = socialEmail
108+
self.serviceAgreement = serviceAgreement
109+
self.collectionAgreement = collectionAgreement
110+
self.advertisementAgreement = advertisementAgreement
111+
self.pushAgreement = pushAgreement
112+
self.name = name
113+
self.birthday = birthday
114+
self.height = height
115+
self.weight = weight
116+
self.cautionNote = cautionNote
117+
self.goalContents = goalContents
118+
}
119+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//
2+
// PostSocialMapper.swift
3+
// Domain
4+
//
5+
// Created by 박서연 on 1/31/25.
6+
// Copyright © 2025 yapp25thTeamTnT. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
public struct PostSocialMapper {
12+
public static func toDTO(from entity: PostSocailEntity) -> PostSocialLoginReqDTO {
13+
return PostSocialLoginReqDTO(
14+
socialType: entity.socialType,
15+
fcmToken: entity.fcmToken,
16+
socialAccessToken: entity.socialAccessToken,
17+
authorizationCode: entity.authorizationCode,
18+
idToken: entity.idToken
19+
)
20+
}
21+
22+
public static func toEntity(from dto: PostSocialLoginReqDTO) -> PostSocailEntity {
23+
return PostSocailEntity(
24+
socialType: dto.socialType,
25+
fcmToken: dto.fcmToken,
26+
socialAccessToken: dto.socialAccessToken,
27+
authorizationCode: dto.authorizationCode,
28+
idToken: dto.idToken
29+
)
30+
}
31+
32+
/// `PostSocialLoginResDTO` → `PostSocialLoginResEntity` 변환
33+
public static func toResEntity(from dto: PostSocialLoginResDTO) -> PostSocialLoginResEntity {
34+
return PostSocialLoginResEntity(
35+
sessionId: dto.sessionId,
36+
socialId: dto.socialId,
37+
socialEmail: dto.socialEmail,
38+
socialType: dto.socialType,
39+
isSignUp: dto.isSignUp
40+
)
41+
}
42+
43+
/// `PostSocialLoginResEntity` → `PostSocialLoginResDTO` 변환
44+
public static func toDTO(from entity: PostSocialLoginResEntity) -> PostSocialLoginResDTO {
45+
return PostSocialLoginResDTO(
46+
sessionId: entity.sessionId,
47+
socialId: entity.socialId,
48+
socialEmail: entity.socialEmail,
49+
socialType: entity.socialType,
50+
isSignUp: entity.isSignUp
51+
)
52+
}
53+
}

TnT/Projects/Domain/Sources/Repository/SocialLoginRepository.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,4 @@ public protocol SocialLoginRepository {
1414
func appleLogin() async -> AppleLoginInfo?
1515
/// 카카오 로그인을 수행합니다
1616
func kakaoLogin() async -> KakaoLoginInfo?
17-
/// 카카오 로그아웃을 수행합니다
18-
func kakaoLogout() async
1917
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//
2+
// SocialLoginUseCase.swift
3+
// Domain
4+
//
5+
// Created by 박서연 on 1/29/25.
6+
// Copyright © 2025 yapp25thTeamTnT. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
public struct SocialLoginUseCase {
12+
13+
private let socialLoginRepository: SocialLoginRepository
14+
15+
public init(socialLoginRepository: SocialLoginRepository) {
16+
self.socialLoginRepository = socialLoginRepository
17+
}
18+
19+
public func appleLogin() async -> AppleLoginInfo? {
20+
return await socialLoginRepository.appleLogin()
21+
}
22+
23+
public func kakaoLogin() async -> KakaoLoginInfo? {
24+
return await socialLoginRepository.kakaoLogin()
25+
}
26+
}

TnT/Projects/Domain/Sources/UseCase/UserUseCase.swift

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//
88

99
import Dependencies
10+
import Foundation
1011

1112
// MARK: - UserUseCase 프로토콜
1213
public protocol UserUseCase {
@@ -27,13 +28,15 @@ public protocol UserUseCase {
2728
}
2829

2930
// MARK: - Default 구현체
30-
public struct DefaultUserUseCase: UserUseCase {
31-
private let userRepository: UserRepository
31+
public struct DefaultUserUseCase: UserRepository, UserUseCase {
3232

33-
public init(userRepository: UserRepository) {
34-
self.userRepository = userRepository
33+
public let userRepostiory: UserRepository
34+
35+
public init(userRepostiory: UserRepository) {
36+
self.userRepostiory = userRepostiory
3537
}
3638

39+
// MARK: - Usecase
3740
public func validateUserName(_ name: String) -> Bool {
3841
return !name.isEmpty && UserPolicy.userNameInput.textValidation(name)
3942
}
@@ -62,3 +65,15 @@ public struct DefaultUserUseCase: UserUseCase {
6265
return UserPolicy.maxPrecautionLength
6366
}
6467
}
68+
69+
// MARK: - Repository
70+
extension DefaultUserUseCase {
71+
public func postSocialLogin(_ reqDTO: PostSocialLoginReqDTO) async throws -> PostSocialLoginResDTO {
72+
return try await userRepostiory.postSocialLogin(reqDTO)
73+
}
74+
75+
public func postSignUp(_ reqDTO: PostSignUpReqDTO, profileImage: Data?) async throws -> PostSignUpResDTO {
76+
return try await userRepostiory.postSignUp(reqDTO, profileImage: profileImage)
77+
}
78+
}
79+

0 commit comments

Comments
 (0)