From 7f7960084ac385d127d7f68f86bb309567818730 Mon Sep 17 00:00:00 2001 From: opficdev Date: Sat, 31 Jan 2026 13:55:46 +0900 Subject: [PATCH 1/2] =?UTF-8?q?refactor=20MainActor=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DevLog/App/Assembler/InfraAssembler.swift | 3 +-- .../Service/SocialLogin/GoogleAuthenticationService.swift | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/DevLog/App/Assembler/InfraAssembler.swift b/DevLog/App/Assembler/InfraAssembler.swift index 817f334..c0843f7 100644 --- a/DevLog/App/Assembler/InfraAssembler.swift +++ b/DevLog/App/Assembler/InfraAssembler.swift @@ -5,8 +5,7 @@ // Created by 최윤진 on 12/7/25. // -final class InfraAssembler: @MainActor Assembler { - @MainActor +final class InfraAssembler: Assembler { func assemble(_ container: any DIContainer) { container.register( AuthenticationService.self, diff --git a/DevLog/Infra/Service/SocialLogin/GoogleAuthenticationService.swift b/DevLog/Infra/Service/SocialLogin/GoogleAuthenticationService.swift index cd0cfb4..1d096fa 100644 --- a/DevLog/Infra/Service/SocialLogin/GoogleAuthenticationService.swift +++ b/DevLog/Infra/Service/SocialLogin/GoogleAuthenticationService.swift @@ -12,7 +12,6 @@ import FirebaseMessaging import Foundation import GoogleSignIn -@MainActor final class GoogleAuthenticationService: AuthenticationService { private let store = Firestore.firestore() private let functions = Functions.functions(region: "asia-northeast3") From 31ca749684d094228f5a6be32dec6514e88cbb5c Mon Sep 17 00:00:00 2001 From: opficdev Date: Sat, 31 Jan 2026 23:50:42 +0900 Subject: [PATCH 2/2] =?UTF-8?q?refactor:=20MainActor=20=ED=98=B8=EC=B6=9C?= =?UTF-8?q?=20=EB=B6=80=EB=B6=84=EC=9D=B4=20=ED=95=84=EC=9A=94=ED=95=A0=20?= =?UTF-8?q?=EC=8B=9C=20MainActor=EC=9D=84=20=EC=A7=80=EC=A0=95=ED=95=B4?= =?UTF-8?q?=EC=A3=BC=EB=8A=94=20=EA=B2=83=EC=9C=BC=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DevLog/Data/Common/Error+.swift | 4 ++ .../GoogleAuthenticationService.swift | 58 +++++++++++-------- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/DevLog/Data/Common/Error+.swift b/DevLog/Data/Common/Error+.swift index bdc42dd..4405ded 100644 --- a/DevLog/Data/Common/Error+.swift +++ b/DevLog/Data/Common/Error+.swift @@ -21,3 +21,7 @@ enum FirestoreError: Error, LocalizedError { } } } + +enum UIError: Error { + case notFoundTopViewController +} diff --git a/DevLog/Infra/Service/SocialLogin/GoogleAuthenticationService.swift b/DevLog/Infra/Service/SocialLogin/GoogleAuthenticationService.swift index 1d096fa..f03a2b0 100644 --- a/DevLog/Infra/Service/SocialLogin/GoogleAuthenticationService.swift +++ b/DevLog/Infra/Service/SocialLogin/GoogleAuthenticationService.swift @@ -17,28 +17,30 @@ final class GoogleAuthenticationService: AuthenticationService { private let functions = Functions.functions(region: "asia-northeast3") private let messaging = Messaging.messaging() private var user: User? { Auth.auth().currentUser } + private let provider = TopViewControllerProvider() + @MainActor func signIn() async throws -> AuthenticationDataResponse { - guard let topVC = topViewController() else { - throw URLError(.cannotFindHost) + guard let topViewController = provider.topViewController() else { + throw UIError.notFoundTopViewController } - - let gidSignIn = try await GIDSignIn.sharedInstance.signIn(withPresenting: topVC) - - guard let idToken = gidSignIn.user.idToken?.tokenString else { + + let signIn = try await GIDSignIn.sharedInstance.signIn(withPresenting: topViewController) + + guard let idToken = signIn.user.idToken?.tokenString else { throw URLError(.badServerResponse) } - let accessToken = gidSignIn.user.accessToken.tokenString + let accessToken = signIn.user.accessToken.tokenString let credential = GoogleAuthProvider.credential(withIDToken: idToken, accessToken: accessToken) let result = try await Auth.auth().signIn(with: credential) - if let photoURL = gidSignIn.user.profile?.imageURL(withDimension: 200) { + if let photoURL = signIn.user.profile?.imageURL(withDimension: 200) { let changeRequest = result.user.createProfileChangeRequest() changeRequest.photoURL = photoURL - changeRequest.displayName = gidSignIn.user.profile?.name - + changeRequest.displayName = signIn.user.profile?.name + try await changeRequest.commitChanges() } @@ -73,8 +75,11 @@ final class GoogleAuthenticationService: AuthenticationService { } func link(uid: String, email: String) async throws { - guard let topViewController = topViewController() else { - throw URLError(.cannotFindHost) + let topViewController = await MainActor.run { + provider.topViewController() + } + guard let topViewController = topViewController else { + throw UIError.notFoundTopViewController } if GIDSignIn.sharedInstance.hasPreviousSignIn() { @@ -110,27 +115,34 @@ final class GoogleAuthenticationService: AuthenticationService { } -extension GoogleAuthenticationService { - func topViewController(controller: UIViewController? = nil) -> UIViewController? { +final class TopViewControllerProvider { + @MainActor + func topViewController() -> UIViewController? { let keyWindow = UIApplication.shared.connectedScenes .compactMap { $0 as? UIWindowScene } .flatMap { $0.windows } .first { $0.isKeyWindow } - let controller = controller ?? keyWindow?.rootViewController - + let rootController = keyWindow?.rootViewController + + return topViewController(controller: rootController) + } + + @MainActor + private func topViewController(controller: UIViewController?) -> UIViewController? { if let navigationController = controller as? UINavigationController { return topViewController(controller: navigationController.visibleViewController) } - - if let tabController = controller as? UITabBarController, let selected = tabController.selectedViewController { - return topViewController(controller: selected) + + if let tabController = controller as? UITabBarController, + let selectedController = tabController.selectedViewController { + return topViewController(controller: selectedController) } - - if let presented = controller?.presentedViewController { - return topViewController(controller: presented) + + if let presentedController = controller?.presentedViewController { + return topViewController(controller: presentedController) } - + return controller } }