AcaMate_iOS/AcaMate/4. Controller/LoginController.swift

191 lines
6.7 KiB
Swift

//
// LoginController.swift
// AcaMate
//
// Created by Sean Kim on 11/26/24.
//
import Combine
import KakaoSDKCommon
import KakaoSDKAuth
import KakaoSDKUser
import Alamofire
import Foundation
class LoginController {
private var cancellables = Set<AnyCancellable>()
func login(_ type: SNSLoginType) -> AnyPublisher<SNSID,Error> {
switch type {
case .Kakao:
return self.checkKakaoToken()
.handleEvents(receiveCompletion: { completion in
switch completion {
case .failure(let error) :
printLog("KAKAO LOGIN ERROR: \(error)")
case .finished: break
}
})
.eraseToAnyPublisher()
//
case .Apple:
return Fail(error: NSError(domain: "Apple login not implemented", code: 1, userInfo: nil))
.eraseToAnyPublisher()
}
}
func logout(type: SNSLoginType) {
switch type {
case .Kakao:
UserApi.shared.logout { error in
if let error = error {
printLog(error)
}
else {
printLog("LOGOUT SUCCESS")
}
}
case .Apple: break
}
}
}
//MARK: - KAKAO LOGIN
extension LoginController {
///
private func checkKakaoToken() -> Future<SNSID, Error> {
return Future { promise in
//
if AuthApi.hasToken() {
printLog("토큰 있음")
self.analysisKakaoToken()
.flatMap{ token in
self.generateSNSID(token)
}
.sink { completion in
switch completion {
case .failure(let error):
promise(.failure(error))
case .finished: break
}
} receiveValue: { data in
promise(.success(data))
}
.store(in: &self.cancellables)
}
else {
// ->
printLog("토큰 없음")
self.loginKakao()
.flatMap { token in
self.generateSNSID(token)
}
.sink { completion in
switch completion {
case .failure(let error):
promise(.failure(error))
case .finished: break
}
} receiveValue: { data in
promise(.success(data))
}
.store(in: &self.cancellables)
}
}
}
private func generateSNSID(_ token: String) -> Future<SNSID, Error> {
return Future { promise in
var snsId = SNSID()
UserApi.shared.me { user, error in
if let error = error {
promise(.failure(error))
}
else if let user = user, let id = user.id{
snsId.acctType = "kakao"
snsId.snsId = "\(id)"
snsId.snsToken = "\(token)"
if let email = user.kakaoAccount?.email {
snsId.snsEmail = email
}
promise(.success(snsId))
}
}
}
}
/// access
private func analysisKakaoToken() -> Future<String, Error> {
return Future { promise in
UserApi.shared.accessTokenInfo { tokenInfo, error in
if let error = error {
printLog("토큰 유효성 체크 실패 - 로그인 동작 필요")
if let sdkError = error as? SdkError, sdkError.isInvalidTokenError() == true {
//
self.loginKakao()
// sink
.sink { completion in
switch completion {
case .failure(let error):
promise(.failure(error))
case .finished: break
// ? Value
}
} receiveValue: { token in
printLog("로그인 완료 - 토큰 받아옴 : \(token)")
promise(.success(token))
}
.store(in: &self.cancellables)
}
else {
//
promise(.failure(error))
}
}
else {
printLog("토큰 유효성 체크 성공")
// , - API
if let tokenInfo = tokenInfo,
let token = Auth.shared.tokenManager.getToken()?.accessToken {
promise(.success(token))
}
}
}
}
}
private func loginKakao() -> Future<String, Error> {
return Future { promise in
if (UserApi.isKakaoTalkLoginAvailable()) { //
UserApi.shared.loginWithKakaoTalk { oauthToken, error in
if let error = error { //
promise(.failure(error))
}
else if let oauthToken = oauthToken { //
promise(.success(oauthToken.accessToken))
}
}
}
else { //
UserApi.shared.loginWithKakaoAccount { oauthToken, error in
if let error = error { //
promise(.failure(error))
}
else if let oauthToken = oauthToken { //
promise(.success(oauthToken.accessToken))
}
}
}
}
}
}