Skip to content

Commit ab091b1

Browse files
authored
Merge pull request #173 from Nexters/feature/#165-애플-로그인-구현
Feature/#165 애플 로그인 추가 구현
2 parents da54a6a + e35f43a commit ab091b1

File tree

23 files changed

+215
-169
lines changed

23 files changed

+215
-169
lines changed

Projects/App/Sources/AppDelegate.swift

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -34,23 +34,6 @@ final class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate {
3434
store.send(.appDelegate(.didFinishLunching))
3535
return true
3636
}
37-
38-
func application(
39-
_ application: UIApplication,
40-
configurationForConnecting connectingSceneSession: UISceneSession,
41-
options: UIScene.ConnectionOptions
42-
) -> UISceneConfiguration {
43-
let configuration = UISceneConfiguration(
44-
name: nil,
45-
sessionRole: connectingSceneSession.role
46-
)
47-
48-
if connectingSceneSession.role == .windowApplication {
49-
configuration.delegateClass = SceneDelegate.self
50-
}
51-
52-
return configuration
53-
}
5437
}
5538

5639
extension AppDelegate: UNUserNotificationCenterDelegate {

Projects/App/Sources/SceneDelegate.swift

Lines changed: 0 additions & 23 deletions
This file was deleted.

Projects/Domain/Auth/Interface/Sources/API/AuthAPI.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public enum AuthAPI {
1717
case withdraw
1818
case logout(_ logOutRequestDTO: LogOutRequestDTO)
1919
case revoke
20+
case profile(_ requestDTO: ProfileRequestDTO)
2021
}
2122

2223
extension AuthAPI: BaseTargetType {
@@ -32,6 +33,8 @@ extension AuthAPI: BaseTargetType {
3233
return "api/v1/auth/logout"
3334
case .revoke:
3435
return "api/v1/auth/apple/revoke"
36+
case .profile:
37+
return "api/v2/auth/profile"
3538
}
3639
}
3740

@@ -47,6 +50,8 @@ extension AuthAPI: BaseTargetType {
4750
return .post
4851
case .revoke:
4952
return .get
53+
case .profile:
54+
return .post
5055
}
5156
}
5257

@@ -62,6 +67,8 @@ extension AuthAPI: BaseTargetType {
6267
return .requestJSONEncodable(logOutRequestDTO)
6368
case .revoke:
6469
return .requestPlain
70+
case .profile(let requestDTO):
71+
return .requestJSONEncodable(requestDTO)
6572
}
6673
}
6774
}

Projects/Domain/Auth/Interface/Sources/AuthClient.swift

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,28 @@
88
import Foundation
99

1010
public struct AuthClient {
11-
private let signInWithKakao: () async throws -> SignInResponseDTO
12-
private let signInWithApple: () async throws -> SignInResponseDTO
11+
private let signInWithKakao: () async throws -> UserInfo
12+
private let signInWithApple: () async throws -> UserInfo
1313
private let saveToken: (Token) -> Void
1414
private let _checkTokenIsExist: () -> Bool
1515
private let withdraw: () async throws -> Void
1616
private let logout: () async throws -> Void
1717
private let refreshAppleToken: () async throws -> AppleToken
1818
private let _revokeAppleLogin: () async throws -> Void
1919
private let fetchAppleClientSecret: () async throws -> String
20+
private let registerUserProfile: (String) async throws -> Void
2021

2122
public init(
22-
signInWithKakao: @escaping () async throws -> SignInResponseDTO,
23-
signInWithApple: @escaping () async throws -> SignInResponseDTO,
23+
signInWithKakao: @escaping () async throws -> UserInfo,
24+
signInWithApple: @escaping () async throws -> UserInfo,
2425
saveToken: @escaping (Token) -> Void,
2526
checkTokenIsExist: @escaping () -> Bool,
2627
withdraw: @escaping () async throws -> Void,
2728
logout: @escaping () async throws -> Void,
2829
refreshAppleToken: @escaping () async throws -> AppleToken,
2930
revokeAppleLogin: @escaping () async throws -> Void,
30-
fetchAppleClientSecret: @escaping () async throws -> String
31+
fetchAppleClientSecret: @escaping () async throws -> String,
32+
registerUserProfile: @escaping (String) async throws -> Void
3133
) {
3234
self.signInWithKakao = signInWithKakao
3335
self.signInWithApple = signInWithApple
@@ -38,13 +40,14 @@ public struct AuthClient {
3840
self.refreshAppleToken = refreshAppleToken
3941
self._revokeAppleLogin = revokeAppleLogin
4042
self.fetchAppleClientSecret = fetchAppleClientSecret
43+
self.registerUserProfile = registerUserProfile
4144
}
4245

43-
public func signInWithKakao() async throws -> SignInResponseDTO {
46+
public func signInWithKakao() async throws -> UserInfo {
4447
try await signInWithKakao()
4548
}
4649

47-
public func signInWithApple() async throws -> SignInResponseDTO {
50+
public func signInWithApple() async throws -> UserInfo {
4851
try await signInWithApple()
4952
}
5053
public func saveToken(token: Token) {
@@ -74,5 +77,9 @@ public struct AuthClient {
7477
public func fetchAppleClientSecret() async throws -> String {
7578
try await fetchAppleClientSecret()
7679
}
80+
81+
public func registerUserProfile(userName: String) async throws {
82+
try await registerUserProfile(userName)
83+
}
7784
}
7885

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//
2+
// ProfileRequestDTO.swift
3+
// DomainAuth
4+
//
5+
// Created by 임현규 on 8/21/24.
6+
//
7+
8+
import Foundation
9+
10+
public struct ProfileRequestDTO: Encodable {
11+
let birthDay: Int?
12+
let birthMonth: Int?
13+
let birthYear: Int?
14+
let gender: String?
15+
let name: String
16+
17+
public init(
18+
birthDay: Int? = nil,
19+
birthMonth: Int? = nil,
20+
birthYear: Int? = nil,
21+
gender: String? = nil,
22+
name: String
23+
) {
24+
self.birthDay = birthDay
25+
self.birthMonth = birthMonth
26+
self.birthYear = birthYear
27+
self.gender = gender
28+
self.name = name
29+
}
30+
}

Projects/Domain/Auth/Interface/Sources/DTO/Response/SignInResponseDTO.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,18 @@ public struct UserInfo {
1111
public let token: Token
1212
public let isSignUp: Bool
1313
public let isCompletedOnboardingIntroduction: Bool
14+
public var userName: String?
1415

1516
public init(
1617
token: Token,
1718
isSignUp: Bool,
18-
isCompletedOnboardingIntroduction: Bool
19+
isCompletedOnboardingIntroduction: Bool,
20+
userName: String? = nil
1921
) {
2022
self.token = token
2123
self.isSignUp = isSignUp
2224
self.isCompletedOnboardingIntroduction = isCompletedOnboardingIntroduction
25+
self.userName = userName
2326
}
2427
}
2528

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// SignInResult.swift
3+
// DomainAuth
4+
//
5+
// Created by 임현규 on 8/21/24.
6+
//
7+
8+
import Foundation
9+
10+
public struct SignInResult {
11+
public let accessToken: String
12+
public let userName: String?
13+
14+
public init(accessToken: String, userName: String? = nil) {
15+
self.accessToken = accessToken
16+
self.userName = userName
17+
}
18+
}

Projects/Domain/Auth/Interface/Sources/LoginManager/LoginManager.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@ public struct LoginManager {
1818
case sms
1919
}
2020

21-
private var signIn: (_ loginType: LoginType) async throws -> String
21+
private var signIn: (_ loginType: LoginType) async throws -> SignInResult
2222

23-
public init(signIn: @escaping (_ loginType: LoginType) async throws -> String) {
23+
public init(signIn: @escaping (_ loginType: LoginType) async throws -> SignInResult) {
2424
self.signIn = signIn
2525
}
2626

2727
/// 로그인 타입에 따라 Provider로 부터 받은 AuthToken & AccessToken을 반환합니다.
2828
/// - Parameters:
2929
/// - loginType: 로그인하는 Type
30-
public func signIn(loginType: LoginType) async throws -> String {
30+
public func signIn(loginType: LoginType) async throws -> SignInResult {
3131
try await signIn(loginType)
3232
}
3333
}

Projects/Domain/Auth/Sources/AuthClient.swift

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,28 +22,35 @@ extension AuthClient: DependencyKey {
2222

2323
return .init(
2424
signInWithKakao: {
25-
let accessToken = try await loginManager.signIn(loginType: .kakao)
25+
let signInResult = try await loginManager.signIn(loginType: .kakao)
26+
let accessToken = signInResult.accessToken
2627
guard let fcmToken = UserDefaults.standard.string(forKey: "fcmToken")
2728
else {
2829
Log.fault("no fcm token")
2930
fatalError()
3031
}
3132
let data = SignInRequestDTO(code: accessToken, fcmDeviceToken: fcmToken)
3233
let responseData = try await networkManager.reqeust(api: .apiType(AuthAPI.kakao(data)), dto: SignInResponseDTO.self)
33-
return responseData
34+
let userInfo = responseData.toDomain()
35+
return userInfo
3436
},
3537

3638
signInWithApple: {
3739
// TODO: apple Login API로 수정
38-
let accessToken = try await loginManager.signIn(loginType: .apple)
40+
let signInResult = try await loginManager.signIn(loginType: .apple)
41+
let accessToken = signInResult.accessToken
42+
let userName = signInResult.userName
43+
3944
guard let fcmToken = UserDefaults.standard.string(forKey: "fcmToken")
4045
else {
4146
Log.fault("no fcm token")
4247
fatalError()
4348
}
4449
let data = SignInRequestDTO(code: accessToken, fcmDeviceToken: fcmToken)
4550
let responseData = try await networkManager.reqeust(api: .apiType(AuthAPI.apple(data)), dto: SignInResponseDTO.self)
46-
return responseData
51+
var userInfo = responseData.toDomain()
52+
userInfo.userName = userName
53+
return userInfo
4754
},
4855
saveToken: { token in
4956
LocalAuthDataSourceImpl.saveToken(token: token)
@@ -73,6 +80,10 @@ extension AuthClient: DependencyKey {
7380
let responseData = try await networkManager.reqeust(api: .apiType(AuthAPI.revoke), dto: ClientSecretResponseDTO.self)
7481
let clientSecret = responseData.clientSecret
7582
return clientSecret
83+
},
84+
registerUserProfile: { userName in
85+
let requestDTO = ProfileRequestDTO(name: userName)
86+
try await networkManager.reqeust(api: .apiType(AuthAPI.profile(requestDTO)))
7687
}
7788
)
7889
}

Projects/Domain/Auth/Sources/LoginManager/AppleLoginManager.swift

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,16 @@
88
import Foundation
99
import AuthenticationServices
1010

11+
import DomainAuthInterface
1112
import CoreKeyChainStore
1213

1314
final class AppleLoginManager: NSObject, ASAuthorizationControllerDelegate {
14-
typealias IdentityCode = String
1515

16-
private var continuation: CheckedContinuation<IdentityCode, Error>?
16+
private var continuation: CheckedContinuation<SignInResult, Error>?
1717

18-
func signInWithApple() async throws -> IdentityCode {
19-
try await withCheckedThrowingContinuation { continuation in
18+
func signInWithApple() async throws -> SignInResult {
19+
try await withCheckedThrowingContinuation { [weak self] continuation in
20+
guard let self = self else { return }
2021
let request = ASAuthorizationAppleIDProvider().createRequest()
2122
request.requestedScopes = [.fullName, .email]
2223
let controller = ASAuthorizationController(authorizationRequests: [request])
@@ -58,10 +59,16 @@ final class AppleLoginManager: NSObject, ASAuthorizationControllerDelegate {
5859
return
5960
}
6061

62+
6163
let user = credential.user
64+
let fullName = credential.fullName
65+
let name = ((fullName?.familyName ?? "") + (fullName?.givenName ?? ""))
66+
6267
KeyChainTokenStore.shared.save(property: .AppleUserID, value: user)
6368
KeyChainTokenStore.shared.save(property: .AppleAuthCode, value: authorizationCodeString)
64-
continuation?.resume(returning: decodedIdentityToken)
69+
70+
let signInResult = SignInResult(accessToken: decodedIdentityToken, userName: name == "" ? nil : name)
71+
continuation?.resume(returning: signInResult)
6572
continuation = nil
6673
}
6774

Projects/Domain/Auth/Sources/LoginManager/LoginManager.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ extension LoginManager: DependencyKey {
2626
case .apple:
2727
return try await signInWithApple()
2828
case .sms:
29-
return ""
29+
return .init(accessToken: "")
3030
}
3131
}
3232
)
@@ -43,15 +43,15 @@ extension DependencyValues {
4343
// MARK: - Kakao SignIn Methods
4444
extension LoginManager {
4545
@MainActor
46-
private static func signInWithKakao() async throws -> String {
46+
private static func signInWithKakao() async throws -> SignInResult {
4747
var accessToken = ""
4848
if UserApi.isKakaoTalkLoginAvailable() {
4949
accessToken = try await loginWithKakaoTalk()
5050
} else {
5151
accessToken = try await loginWithKakaoAccount()
5252
}
5353

54-
return accessToken
54+
return .init(accessToken: accessToken)
5555
}
5656

5757
@MainActor
@@ -93,10 +93,10 @@ extension LoginManager {
9393

9494
// MARK: - Apple Login Methods
9595
private extension LoginManager {
96-
static func signInWithApple() async throws -> String {
96+
static func signInWithApple() async throws -> SignInResult {
9797
let appleLoginManager = AppleLoginManager()
98-
let identityToken = try await appleLoginManager.signInWithApple()
99-
return identityToken
98+
let signInResult = try await appleLoginManager.signInWithApple()
99+
return signInResult
100100
}
101101
}
102102

0 commit comments

Comments
 (0)