Skip to content

Commit

Permalink
refactor/ #273 온보딩프로세스 task 로 refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
hooni0918 committed Aug 3, 2024
1 parent 0629af8 commit 7ae2498
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 102 deletions.
2 changes: 1 addition & 1 deletion KkuMulKum/Application/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
DispatchQueue.main.async {
if success {
print("Auto login successful, showing main screen")
self?.showMainScreen()
self?.showLoginScreen()
} else {
print("Auto login failed, showing login screen")
self?.showLoginScreen()
Expand Down
52 changes: 26 additions & 26 deletions KkuMulKum/Network/Service/AuthService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ protocol AuthServiceType {
func getAccessToken() -> String?
func getRefreshToken() -> String?
func clearTokens() -> Bool
func performRequest<T: ResponseModelType>(_ target: AuthTargetType, completion: @escaping (Result<T, NetworkError>) -> Void)
func performRequest<T: ResponseModelType>(_ target: AuthTargetType) async throws -> T
}

class AuthService: AuthServiceType {
Expand Down Expand Up @@ -48,34 +48,34 @@ class AuthService: AuthServiceType {
return keychainService.accessToken == nil && keychainService.refreshToken == nil
}

func performRequest<T: ResponseModelType>(_ target: AuthTargetType, completion: @escaping (Result<T, NetworkError>) -> Void) {
provider.request(target) { result in
switch result {
case .success(let response):
print("서버 응답 상태 코드: \(response.statusCode)")
print("서버 응답 데이터: \(String(data: response.data, encoding: .utf8) ?? "디코딩 불가")")

do {
let decodedResponse = try JSONDecoder().decode(ResponseBodyDTO<T>.self, from: response.data)
if decodedResponse.success {
if let data = decodedResponse.data {
completion(.success(data))
} else if T.self == EmptyModel.self {
completion(.success(EmptyModel() as! T))
} else {
completion(.failure(.decodingError))
func performRequest<T: ResponseModelType>(_ target: AuthTargetType) async throws -> T {
return try await withCheckedThrowingContinuation { continuation in
provider.request(target) { result in
switch result {
case .success(let response):
print("서버 응답 상태 코드: \(response.statusCode)")
print("서버 응답 데이터: \(String(data: response.data, encoding: .utf8) ?? "디코딩 불가")")

do {
let decodedResponse = try JSONDecoder().decode(ResponseBodyDTO<T>.self, from: response.data)
guard decodedResponse.success else {
throw decodedResponse.error.map(self.mapErrorResponse) ?? NetworkError.unknownError("Unknown error occurred")
}
} else if let error = decodedResponse.error {
completion(.failure(self.mapErrorResponse(error)))
} else {
completion(.failure(.unknownError("Unknown error occurred")))
guard let data = decodedResponse.data else {
if T.self == EmptyModel.self {
continuation.resume(returning: EmptyModel() as! T)
} else {
throw NetworkError.decodingError
}
return
}
continuation.resume(returning: data)
} catch {
continuation.resume(throwing: error is NetworkError ? error : NetworkError.decodingError)
}
} catch {
print("디코딩 오류: \(error)")
completion(.failure(.decodingError))
case .failure(let error):
continuation.resume(throwing: NetworkError.networkError(error))
}
case .failure(let error):
completion(.failure(.networkError(error)))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ class LoginViewModel: NSObject {
}
}
}

private func clearTokensAndHandleError() {
_ = authService.clearTokens()
loginState.value = .notLogin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import UIKit
class LoginViewController: BaseViewController {
private let loginView = LoginView()
private let loginViewModel: LoginViewModel

init(viewModel: LoginViewModel) {
self.loginViewModel = viewModel
super.init(nibName: nil, bundle: nil)
Expand Down Expand Up @@ -48,44 +48,55 @@ class LoginViewController: BaseViewController {

private func bindViewModel() {
loginViewModel.loginState.bind(with: self) { owner, state in
switch state {
case .notLogin:
print("Login State: Not logged in")
case .login:
print("Login State: Logged in")
owner.navigateToMainScreen()
case .needOnboarding:
print("Login State: Need onboarding")
owner.navigateToOnboardingScreen()

Task {
switch state {
case .notLogin:
print("Login State: Not logged in")
case .login:
print("Login State: Logged in")
await owner.navigateToMainScreen()
case .needOnboarding:
print("Login State: Need onboarding")
await owner.navigateToOnboardingScreen()
}
}
}

loginViewModel.userName.bind(with: self) { owner, name in
if name != nil {
owner.navigateToMainScreen()
} else {
owner.navigateToOnboardingScreen()
Task {
if name != nil {
await owner.navigateToOnboardingScreen()
} else {
await owner.navigateToOnboardingScreen()
}
}
}

loginViewModel.error.bind(with: self) { owner, error in
if !error.isEmpty {
print("Login Error: \(error)")
owner.showErrorAlert(message: error)
Task {
if !error.isEmpty {
print("Login Error: \(error)")
await owner.showErrorAlert(message: error)
}
}
}
}

@objc private func appleLoginTapped() {
loginViewModel.performAppleLogin(presentationAnchor: view.window!)
Task {
loginViewModel.performAppleLogin(presentationAnchor: view.window!)
}
}

@objc private func kakaoLoginTapped() {
loginViewModel.performKakaoLogin()
Task {
loginViewModel.performKakaoLogin()
}
}

private func navigateToMainScreen() {
DispatchQueue.main.async {
private func navigateToMainScreen() async {
await MainActor.run {
let mainTabBarController = MainTabBarController()
let navigationController = UINavigationController(rootViewController: mainTabBarController)
navigationController.isNavigationBarHidden = true
Expand All @@ -95,8 +106,9 @@ class LoginViewController: BaseViewController {
}
}

private func navigateToOnboardingScreen() {
DispatchQueue.main.async {
private func navigateToOnboardingScreen() async {
await MainActor.run {

let nicknameViewController = NicknameViewController()
if let navigationController = self.navigationController {
navigationController.pushViewController(nicknameViewController, animated: true)
Expand All @@ -109,10 +121,12 @@ class LoginViewController: BaseViewController {
}
}

private func showErrorAlert(message: String) {
print("Showing error alert with message: \(message)")
let alert = UIAlertController(title: "Error", message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default))
present(alert, animated: true)
private func showErrorAlert(message: String) async {
await MainActor.run {
print("Showing error alert with message: \(message)")
let alert = UIAlertController(title: "Error", message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default))
present(alert, animated: true)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,19 @@ class ProfileSetupViewController: BaseViewController {
}

@objc private func confirmButtonTapped() {
viewModel.uploadProfileImage { [weak self] success in
if success {
DispatchQueue.main.async {
let welcomeVC = WelcomeViewController(
viewModel: WelcomeViewModel(nickname: self?.viewModel.nickname ?? "")
)
welcomeVC.modalPresentationStyle = .fullScreen
self?.present(welcomeVC, animated: true, completion: nil)
}
}
}
}
Task {
let success = await viewModel.uploadProfileImage()
if success {
DispatchQueue.main.async {
let welcomeVC = WelcomeViewController(
viewModel: WelcomeViewModel(nickname: self.viewModel.nickname)
)
welcomeVC.modalPresentationStyle = .fullScreen
self.present(welcomeVC, animated: true, completion: nil)
}
}
}
}

@objc private func skipButtonTapped() {
let welcomeVC = WelcomeViewController(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,39 +32,35 @@ class ProfileSetupViewModel {
isConfirmButtonEnabled.value = imageData != nil
}

func uploadProfileImage(completion: @escaping (Bool) -> Void) {
print("uploadProfileImage 함수 호출됨")
guard let imageData = imageData else {
print("이미지 데이터가 없습니다.")
serverResponse.value = "이미지 데이터가 없습니다."
completion(false)
return
}

print("업로드할 이미지 데이터 크기: \(imageData.count) bytes")

let fileName = "profile_image.jpg"
let mimeType = "image/jpeg"

authService.performRequest(
.updateProfileImage(
image: imageData,
fileName: fileName,
mimeType: mimeType
)
) { [weak self] (result: Result<EmptyModel, NetworkError>) in
print("네트워크 요청 완료")
switch result {
case .success(_):
self?.serverResponse.value = "프로필 이미지가 성공적으로 업로드되었습니다."
print("프로필 이미지 업로드 성공")
completion(true)
case .failure(let error):
self?.handleError(error)
completion(false)
}
}
}
func uploadProfileImage() async -> Bool {
print("uploadProfileImage 함수 호출됨")
guard let imageData = imageData else {
print("이미지 데이터가 없습니다.")
serverResponse.value = "이미지 데이터가 없습니다."
return false
}

print("업로드할 이미지 데이터 크기: \(imageData.count) bytes")

let fileName = "profile_image.jpg"
let mimeType = "image/jpeg"

do {
let _: EmptyModel = try await authService.performRequest(
.updateProfileImage(
image: imageData,
fileName: fileName,
mimeType: mimeType
)
)
serverResponse.value = "프로필 이미지가 성공적으로 업로드되었습니다."
print("프로필 이미지 업로드 성공")
return true
} catch {
handleError(error as? NetworkError ?? .unknownError("알 수 없는 오류가 발생했습니다."))
return false
}
}

private func handleError(_ error: NetworkError) {
serverResponse.value = error.message
Expand Down

0 comments on commit 7ae2498

Please sign in to comment.