Skip to content

Commit

Permalink
[Feat] #468 - Apple에서 받은 identityToken으로 메이커스 로그인 api 연동
Browse files Browse the repository at this point in the history
  • Loading branch information
meltsplit committed Jan 18, 2025
1 parent 1d8d045 commit b167eff
Show file tree
Hide file tree
Showing 17 changed files with 215 additions and 57 deletions.
11 changes: 11 additions & 0 deletions SOPT-iOS/Projects/Core/Sources/Literals/UserDefaultKeyLIst.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
import Foundation

public struct UserDefaultKeyList {

public struct CoreAuth {
@UserDefaultWrapper<String>(key: "accessToken") public static var accessToken
@UserDefaultWrapper<String>(key: "refreshToken") public static var refreshToken
}

public struct Auth {
@UserDefaultWrapper<String>(key: "appAccessToken") public static var appAccessToken
@UserDefaultWrapper<String>(key: "appRefreshToken") public static var appRefreshToken
Expand Down Expand Up @@ -48,6 +54,11 @@ extension UserDefaultKeyList {
UserDefaultKeyList.Auth.isActiveUser = nil
}

public static func clearCoreUserData() {
UserDefaultKeyList.CoreAuth.accessToken = nil
UserDefaultKeyList.CoreAuth.refreshToken = nil
}

public static func clearPushToken() {
UserDefaultKeyList.User.pushToken = nil
}
Expand Down
49 changes: 35 additions & 14 deletions SOPT-iOS/Projects/Data/Sources/Repository/CoreAuthRepository.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// CoreOAuthRepository.swift
// CoreAuthRepository.swift
// Data
//
// Created by 장석우 on 1/18/25.
Expand All @@ -9,25 +9,46 @@
import Combine
import Foundation

import Core
import Domain
import Networks

public class CoreOAuthRepository {
public struct CoreAuthRepository {
private let coreAuthService: CoreAuthService

private let appleService: AuthenticationService
// private let googleService:

public init(appleService: AuthenticationService) {
self.appleService = appleService
public init(coreAuthService: CoreAuthService) {
self.coreAuthService = coreAuthService
}
}

extension CoreOAuthRepository: CoreOAuthRepositoryInterface {
public func getIdentityToken(from provider: OAuthType) -> AnyPublisher<String, Domain.CoreAuthError> {
switch provider {
case .apple: return appleService.getIdentityToken()
case .google: fatalError() //TODO:
}

extension CoreAuthRepository: CoreAuthRepositoryInterface {

public func login(
for provider: OAuthType,
with identityToken: String
) -> AnyPublisher<CoreAuthTokens, CoreAuthError> {
coreAuthService
.login(.dto(token: identityToken, oauthType: provider))
.compactMap { $0.data?.toDomain() }
.mapError { _ in CoreAuthError.makers(.loginFail) }
.eraseToAnyPublisher()
}

public func saveTokens(_ tokens: Domain.CoreAuthTokens) {
UserDefaultKeyList.CoreAuth.accessToken = tokens.accessToken
UserDefaultKeyList.CoreAuth.refreshToken = tokens.refreshToken
}

public func changeSocialAccount() -> AnyPublisher<Void, CoreAuthError> {
fatalError()
}

public func searchSocialAccount() -> AnyPublisher<Void, CoreAuthError> {
fatalError()
}

public func signUp(_ model: Domain.SignUpModel) -> AnyPublisher<Void, CoreAuthError> {
fatalError()
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// CoreOAuthRepository.swift
// Data
//
// Created by 장석우 on 1/18/25.
// Copyright © 2025 SOPT-iOS. All rights reserved.
//

import Combine
import Foundation

import Domain
import Networks

public class CoreOAuthRepository {

private let appleService: AuthenticationService
// private let googleService:

public init(appleService: AuthenticationService) {
self.appleService = appleService
}
}

extension CoreOAuthRepository: CoreOAuthRepositoryInterface {
public func getIdentityToken(from provider: OAuthType) -> AnyPublisher<String, Domain.CoreAuthError> {
switch provider {
case .apple: return appleService.getIdentityToken()
case .google: fatalError() //TODO:
}

}
}
31 changes: 31 additions & 0 deletions SOPT-iOS/Projects/Data/Sources/Transform/LoginTransform.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// LoginTransform.swift
// Data
//
// Created by 장석우 on 1/18/25.
// Copyright © 2025 SOPT-iOS. All rights reserved.
//

import Foundation

import Domain
import Networks

extension CoreLoginRequestEntity {
static func dto(token: String, oauthType: OAuthType) -> Self {
var platform: PlatformType

switch oauthType {
case .apple: platform = .apple
case .google: platform = .google
}

return .init(token: token, authPlatform: platform)
}
}

extension CoreLoginEntity {
public func toDomain() -> CoreAuthTokens {
.init(accessToken: accessToken, refreshToken: refreshToken)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ extension AppDelegate {
}
)

container.register(
interface: CoreAuthRepositoryInterface.self,
implement: {
CoreAuthRepository(coreAuthService: DefaultCoreAuthService())
}
)

container.register(
interface: SplashRepositoryInterface.self,
implement: {
Expand Down
5 changes: 5 additions & 0 deletions SOPT-iOS/Projects/Domain/Sources/Error/CoreAuthError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Foundation
public enum CoreAuthError: Error {
case apple(Apple)
case google(Google)
case makers(Makers)
case unknown(Error)

public enum Apple: Error {
Expand All @@ -22,4 +23,8 @@ public enum CoreAuthError: Error {
public enum Google: Error {

}

public enum Makers: Error {
case loginFail
}
}
19 changes: 19 additions & 0 deletions SOPT-iOS/Projects/Domain/Sources/Model/CoreAuthTokens.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// CoreAuthTokens.swift
// Domain
//
// Created by 장석우 on 1/18/25.
// Copyright © 2025 SOPT-iOS. All rights reserved.
//

import Foundation

public struct CoreAuthTokens {
public let accessToken: String
public let refreshToken: String

public init(accessToken: String, refreshToken: String) {
self.accessToken = accessToken
self.refreshToken = refreshToken
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// CoreAuthRepositoryInterface.swift
// Domain
//
// Created by 장석우 on 12/20/24.
// Copyright © 2024 SOPT-iOS. All rights reserved.
//

import Combine

public protocol CoreAuthRepositoryInterface {
func login(for provider: OAuthType,with identityToken: String) -> AnyPublisher<CoreAuthTokens, CoreAuthError>
func changeSocialAccount() -> AnyPublisher<Void, CoreAuthError>
func searchSocialAccount() -> AnyPublisher<Void, CoreAuthError>
func signUp(_ model: SignUpModel) -> AnyPublisher<Void, CoreAuthError>
func saveTokens(_ tokens: CoreAuthTokens) -> Void
}
35 changes: 25 additions & 10 deletions SOPT-iOS/Projects/Domain/Sources/UseCase/SignInUseCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,52 @@ public enum SiginInHandleableType {

public protocol SignInUseCase {
func requestSignIn(token: String)
func login(with provider: OAuthType) -> AnyPublisher<String, Never>
func login(with provider: OAuthType) -> AnyPublisher<Void, Never>

var sideEffect: PassthroughSubject<CoreAuthError, Never> { get }
var signInSuccess: CurrentValueSubject<SiginInHandleableType, Error> { get set }
}

public class DefaultSignInUseCase {

private let repository: SignInRepositoryInterface
private let oauthRepository: CoreOAuthRepositoryInterface
private let coreRepository: CoreAuthRepositoryInterface

private var cancelBag = CancelBag()

public var sideEffect = PassthroughSubject<CoreAuthError, Never>()
public var signInSuccess = CurrentValueSubject<SiginInHandleableType, Error>(.loginFailure)

public init(
repository: SignInRepositoryInterface,
oauthRepository: CoreOAuthRepositoryInterface
oauthRepository: CoreOAuthRepositoryInterface,
coreRepository: CoreAuthRepositoryInterface
) {
self.repository = repository
self.oauthRepository = oauthRepository
self.coreRepository = coreRepository
}
}

//MARK: - 인증중앙화(CoreAuth) 로직
extension DefaultSignInUseCase: SignInUseCase {
public func login(with provider: OAuthType) -> AnyPublisher<Void, Never> {
oauthRepository.getIdentityToken(from: .apple)
.map { (provider, $0) }
.flatMap(coreRepository.login)
.handleEvents(receiveOutput: coreRepository.saveTokens)
.mapVoid()
.catch { [weak self] in
self?.sideEffect.send($0)
return Empty<Void, Never>()
}
.eraseToAnyPublisher()
}
}

//MARK: - LegacyAuth 로직
extension DefaultSignInUseCase {
public func requestSignIn(token: String) {
repository.requestSignIn(token: token)
.sink { event in
Expand All @@ -54,12 +77,4 @@ extension DefaultSignInUseCase: SignInUseCase {
self.signInSuccess.send(isSuccessed ? .loginSuccess : .loginFailure)
}.store(in: self.cancelBag)
}

public func login(with provider: OAuthType) -> AnyPublisher<String, Never> {
oauthRepository.getIdentityToken(from: .apple)
.catch { _ in
return Empty<String, Never>()
}
.eraseToAnyPublisher()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,19 @@ public
final class AuthBuilder {
@Injected public var repository: SignInRepositoryInterface
@Injected public var oauthRepository: CoreOAuthRepositoryInterface
@Injected public var coreRepository: CoreAuthRepositoryInterface

public init() { }
}

extension AuthBuilder: AuthFeatureViewBuildable {

public func makeSignIn() -> SignInPresentable {
let useCase = DefaultSignInUseCase(repository: repository, oauthRepository: oauthRepository)
let useCase = DefaultSignInUseCase(
repository: repository,
oauthRepository: oauthRepository,
coreRepository: coreRepository
)
let vm = SignInViewModel(useCase: useCase)
let vc = SignInVC()
vc.viewModel = vm
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ extension SignInViewModel {
input.appleLoginButtonTapped.map { OAuthType.apple }
).flatMap(useCase.login)
.withUnretained(self)
.sink { owner, id in
print(id)
.sink { owner, _ in
print("로그인 성공")
}.store(in: self.cancelBag)

input.signUpButtonTapped
Expand Down Expand Up @@ -104,5 +104,11 @@ extension SignInViewModel {
} receiveValue: { (owner, isSignInSuccess) in
owner.onSignInSuccess?(isSignInSuccess)
}.store(in: self.cancelBag)

useCase.sideEffect
.sink { event in
print(event)
}
.store(in: self.cancelBag)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public enum CoreAuthAPI {
case sendVerifyCode(dto: SendVerificationCodeEntity)
case verfiyCode(dto: VerifyCodeEntity)
case signUp(dto: SignUpEntity)
case login(dto: LoginEntity)
case login(dto: CoreLoginRequestEntity)
}

extension CoreAuthAPI: BaseAPI {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@

import Foundation

public struct LoginEntity: Encodable {
let code: String
public struct CoreLoginRequestEntity: Encodable {
let token: String
let authPlatform: PlatformType

public init(code: String, authPlatform: PlatformType) {
self.code = code
public init(token: String, authPlatform: PlatformType) {
self.token = token
self.authPlatform = authPlatform
}
}
Loading

0 comments on commit b167eff

Please sign in to comment.