LINE 로그인 지원 추가
LINE 로그인 요청과 토큰 처리 흐름을 추가함
This commit is contained in:
@@ -150,6 +150,7 @@ struct LoginView: View {
|
||||
Image("ic_login_line")
|
||||
.onTapGesture {
|
||||
hideKeyboard()
|
||||
viewModel.loginWithLine()
|
||||
}
|
||||
|
||||
Image("ic_login_x")
|
||||
|
||||
@@ -15,12 +15,14 @@ import UIKit
|
||||
import GoogleSignIn
|
||||
import KakaoSDKUser
|
||||
import KakaoSDKAuth
|
||||
import LineSDK
|
||||
|
||||
final class LoginViewModel: NSObject, ObservableObject {
|
||||
private let appViewModel = AppViewModel()
|
||||
private let repository = UserRepository()
|
||||
private var subscription = Set<AnyCancellable>()
|
||||
private var currentNonce: String?
|
||||
private var currentLineNonce: String?
|
||||
|
||||
@Published var email = ""
|
||||
@Published var password = ""
|
||||
@@ -127,6 +129,49 @@ final class LoginViewModel: NSObject, ObservableObject {
|
||||
KakaoSDKUser.UserApi.shared.loginWithKakaoAccount(completion: loginHandler)
|
||||
}
|
||||
}
|
||||
|
||||
func loginWithLine() {
|
||||
guard let presentingViewController = presentingViewController() else {
|
||||
self.errorMessage = I18n.Login.Line.openFailed
|
||||
self.isShowPopup = true
|
||||
return
|
||||
}
|
||||
|
||||
let nonce = randomNonceString()
|
||||
currentLineNonce = nonce
|
||||
|
||||
var parameters = LoginManager.Parameters()
|
||||
parameters.IDTokenNonce = nonce
|
||||
|
||||
DispatchQueue.main.async {
|
||||
LoginManager.shared.login(permissions: [.profile, .openID], in: presentingViewController, parameters: parameters) { result in
|
||||
switch result {
|
||||
case .success(let loginResult):
|
||||
guard let identityToken = loginResult.accessToken.IDTokenRaw, !identityToken.isEmpty else {
|
||||
self.currentLineNonce = nil
|
||||
self.errorMessage = I18n.Login.Line.tokenMissing
|
||||
self.isShowPopup = true
|
||||
return
|
||||
}
|
||||
|
||||
guard let lineNonce = self.currentLineNonce else {
|
||||
self.errorMessage = I18n.Common.commonError
|
||||
self.isShowPopup = true
|
||||
return
|
||||
}
|
||||
|
||||
self.currentLineNonce = nil
|
||||
self.loginWithLine(identityToken: identityToken, nonce: lineNonce)
|
||||
|
||||
case .failure(let error):
|
||||
self.currentLineNonce = nil
|
||||
ERROR_LOG(error.localizedDescription)
|
||||
self.errorMessage = I18n.Login.Line.signInFailed
|
||||
self.isShowPopup = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func loginWithApple(identityToken: String, nonce: String) {
|
||||
let pushToken = UserDefaults.string(forKey: .pushToken)
|
||||
@@ -209,6 +254,33 @@ final class LoginViewModel: NSObject, ObservableObject {
|
||||
.store(in: &subscription)
|
||||
}
|
||||
|
||||
private func loginWithLine(identityToken: String, nonce: String) {
|
||||
let pushToken = UserDefaults.string(forKey: .pushToken)
|
||||
let marketingPid = UserDefaults.string(forKey: .marketingPid)
|
||||
let request = SocialLoginRequest(
|
||||
container: "ios",
|
||||
pushToken: pushToken.isEmpty ? nil : pushToken,
|
||||
marketingPid: marketingPid.isEmpty ? nil : marketingPid,
|
||||
identityToken: identityToken,
|
||||
nonce: nonce
|
||||
)
|
||||
|
||||
isLoading = true
|
||||
repository.loginLine(request: request)
|
||||
.sink { result in
|
||||
switch result {
|
||||
case .finished:
|
||||
DEBUG_LOG("finish")
|
||||
case .failure(let error):
|
||||
self.isLoading = false
|
||||
ERROR_LOG(error.localizedDescription)
|
||||
}
|
||||
} receiveValue: { response in
|
||||
self.handleLoginResponse(response)
|
||||
}
|
||||
.store(in: &subscription)
|
||||
}
|
||||
|
||||
private func presentingViewController() -> UIViewController? {
|
||||
return UIApplication.shared.connectedScenes
|
||||
.compactMap { $0 as? UIWindowScene }
|
||||
|
||||
@@ -13,6 +13,7 @@ enum UserApi {
|
||||
case loginApple(request: SocialLoginRequest)
|
||||
case loginGoogle(request: SocialLoginRequest, idToken: String)
|
||||
case loginKakao(request: SocialLoginRequest, accessToken: String)
|
||||
case loginLine(request: SocialLoginRequest)
|
||||
case signUp(request: SignUpRequest)
|
||||
case findPassword(request: ForgotPasswordRequest)
|
||||
case searchUser(nickname: String)
|
||||
@@ -58,6 +59,9 @@ extension UserApi: TargetType {
|
||||
|
||||
case .loginKakao:
|
||||
return "/member/login/kakao"
|
||||
|
||||
case .loginLine:
|
||||
return "/member/login/line"
|
||||
|
||||
case .signUp:
|
||||
return "/member/signup/v2"
|
||||
@@ -132,7 +136,7 @@ extension UserApi: TargetType {
|
||||
|
||||
var method: Moya.Method {
|
||||
switch self {
|
||||
case .login, .loginApple, .loginGoogle, .loginKakao, .signUp, .findPassword, .notification, .logout, .logoutAllDevice, .signOut, .creatorFollow, .creatorUnFollow, .memberBlock, .memberUnBlock,
|
||||
case .login, .loginApple, .loginGoogle, .loginKakao, .loginLine, .signUp, .findPassword, .notification, .logout, .logoutAllDevice, .signOut, .creatorFollow, .creatorUnFollow, .memberBlock, .memberUnBlock,
|
||||
.profileImageUpdate:
|
||||
return .post
|
||||
|
||||
@@ -157,6 +161,9 @@ extension UserApi: TargetType {
|
||||
|
||||
case .loginKakao(let request, _):
|
||||
return .requestJSONEncodable(request)
|
||||
|
||||
case .loginLine(let request):
|
||||
return .requestJSONEncodable(request)
|
||||
|
||||
case .signUp(let request):
|
||||
return .requestJSONEncodable(request)
|
||||
@@ -220,7 +227,7 @@ extension UserApi: TargetType {
|
||||
|
||||
var headers: [String : String]? {
|
||||
switch self {
|
||||
case .login, .loginApple, .signUp, .findPassword:
|
||||
case .login, .loginApple, .loginLine, .signUp, .findPassword:
|
||||
return nil
|
||||
|
||||
case .loginGoogle(_, let idToken):
|
||||
|
||||
@@ -28,6 +28,10 @@ final class UserRepository {
|
||||
func loginKakao(request: SocialLoginRequest, accessToken: String) -> AnyPublisher<Response, MoyaError> {
|
||||
return api.requestPublisher(.loginKakao(request: request, accessToken: accessToken))
|
||||
}
|
||||
|
||||
func loginLine(request: SocialLoginRequest) -> AnyPublisher<Response, MoyaError> {
|
||||
return api.requestPublisher(.loginLine(request: request))
|
||||
}
|
||||
|
||||
func signUp(request: SignUpRequest) -> AnyPublisher<Response, MoyaError> {
|
||||
return api.requestPublisher(.signUp(request: request))
|
||||
|
||||
Reference in New Issue
Block a user