From d1f88e0babc246f31767885201ed87d7828fd0fa Mon Sep 17 00:00:00 2001 From: mini-min <2alswo7@khu.ac.kr> Date: Thu, 5 Mar 2026 12:43:19 +0900 Subject: [PATCH 1/4] =?UTF-8?q?[Refactor]=20#264=20-=20=20STRICT=5FCONCURR?= =?UTF-8?q?ENCY=20targeted=20=EC=83=81=ED=96=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TOASTER-iOS.xcodeproj/project.pbxproj | 12 +++++++----- .../xcshareddata/xcschemes/TOASTER-iOS.xcscheme | 2 +- TOASTER-iOS/Network/Base/APIInterceptor.swift | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/TOASTER-iOS.xcodeproj/project.pbxproj b/TOASTER-iOS.xcodeproj/project.pbxproj index eb4e5272..1d5cb31c 100644 --- a/TOASTER-iOS.xcodeproj/project.pbxproj +++ b/TOASTER-iOS.xcodeproj/project.pbxproj @@ -1911,7 +1911,7 @@ attributes = { BuildIndependentTargetsInParallel = 1; LastSwiftUpdateCheck = 1530; - LastUpgradeCheck = 1620; + LastUpgradeCheck = 2630; TargetAttributes = { 3FF2BEFE2BA17492001D7DC1 = { CreatedOnToolsVersion = 15.3; @@ -2343,7 +2343,6 @@ CODE_SIGN_ENTITLEMENTS = ToasterShareExtension/ToasterShareExtension.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = JF6B89ULG6; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = ToasterShareExtension/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = ToasterShareExtension; @@ -2370,7 +2369,6 @@ CODE_SIGN_ENTITLEMENTS = ToasterShareExtension/ToasterShareExtension.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = JF6B89ULG6; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = ToasterShareExtension/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = ToasterShareExtension; @@ -2427,6 +2425,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = JF6B89ULG6; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; ENABLE_USER_SCRIPT_SANDBOXING = YES; @@ -2450,8 +2449,10 @@ MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; + STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_STRICT_CONCURRENCY = targeted; }; name = Debug; }; @@ -2491,6 +2492,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = JF6B89ULG6; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_USER_SCRIPT_SANDBOXING = YES; @@ -2507,7 +2509,9 @@ MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = iphoneos; + STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_STRICT_CONCURRENCY = targeted; VALIDATE_PRODUCT = YES; }; name = Release; @@ -2521,7 +2525,6 @@ CODE_SIGN_ENTITLEMENTS = "TOASTER-iOS/TOASTER-iOS.entitlements"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = JF6B89ULG6; ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "TOASTER-iOS/Global/Supporting Files/Info.plist"; @@ -2555,7 +2558,6 @@ CODE_SIGN_ENTITLEMENTS = "TOASTER-iOS/TOASTER-iOS.entitlements"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = JF6B89ULG6; ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "TOASTER-iOS/Global/Supporting Files/Info.plist"; diff --git a/TOASTER-iOS.xcodeproj/xcshareddata/xcschemes/TOASTER-iOS.xcscheme b/TOASTER-iOS.xcodeproj/xcshareddata/xcschemes/TOASTER-iOS.xcscheme index 90fca5cc..00172b4b 100644 --- a/TOASTER-iOS.xcodeproj/xcshareddata/xcschemes/TOASTER-iOS.xcscheme +++ b/TOASTER-iOS.xcodeproj/xcshareddata/xcschemes/TOASTER-iOS.xcscheme @@ -1,6 +1,6 @@ Date: Thu, 5 Mar 2026 14:11:06 +0900 Subject: [PATCH 2/4] =?UTF-8?q?[Refactor]=20#264=20-=20Concurrency=20Check?= =?UTF-8?q?ing=20Complete=20=EC=83=81=ED=96=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TOASTER-iOS.xcodeproj/project.pbxproj | 6 ++++-- TOASTER-iOS/Application/Coordinator/Coordinator.swift | 1 + .../Application/Coordinator/CoordinatorFinishOutput.swift | 1 + .../Coordinator/Coordinators/TabBarCoordinator.swift | 4 +++- .../Coordinator/Factory/CoordinatorFactory.swift | 1 + .../Coordinator/Factory/ViewControllerFactory.swift | 1 + TOASTER-iOS/Application/Coordinator/Router.swift | 1 + TOASTER-iOS/Present/AddLink/View/SelectClipHeaderView.swift | 1 + .../Clip/View/Component/AddClipBottomSheetView.swift | 1 + .../Clip/View/Component/ClipCollectionHeaderView.swift | 1 + .../View/Cell/DetailClipListCollectionViewCell.swift | 1 + .../View/Component/ChangeClipBottomSheetView.swift | 1 + .../Present/Home/View/Cell/UserClipCollectionViewCell.swift | 1 + .../Present/Home/View/Component/CompositioinalFactory.swift | 1 + .../View/Component/RemindAlarmOffBottomSheetView.swift | 1 + .../View/Component/RemindTimerEditBottomSheetView.swift | 1 + .../TimerAdd/View/TimerRepeatBottomSheetView.swift | 1 + TOASTER-iOS/Present/UpdateAlert/UpdateAlertManager.swift | 3 ++- 18 files changed, 24 insertions(+), 4 deletions(-) diff --git a/TOASTER-iOS.xcodeproj/project.pbxproj b/TOASTER-iOS.xcodeproj/project.pbxproj index 1d5cb31c..85c83e91 100644 --- a/TOASTER-iOS.xcodeproj/project.pbxproj +++ b/TOASTER-iOS.xcodeproj/project.pbxproj @@ -2451,8 +2451,9 @@ SDKROOT = iphoneos; STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_DEFAULT_ACTOR_ISOLATION = nonisolated; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_STRICT_CONCURRENCY = targeted; + SWIFT_STRICT_CONCURRENCY = complete; }; name = Debug; }; @@ -2511,7 +2512,8 @@ SDKROOT = iphoneos; STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_STRICT_CONCURRENCY = targeted; + SWIFT_DEFAULT_ACTOR_ISOLATION = nonisolated; + SWIFT_STRICT_CONCURRENCY = complete; VALIDATE_PRODUCT = YES; }; name = Release; diff --git a/TOASTER-iOS/Application/Coordinator/Coordinator.swift b/TOASTER-iOS/Application/Coordinator/Coordinator.swift index 68266a34..c0237bb8 100644 --- a/TOASTER-iOS/Application/Coordinator/Coordinator.swift +++ b/TOASTER-iOS/Application/Coordinator/Coordinator.swift @@ -7,6 +7,7 @@ import Foundation +@MainActor protocol Coordinator: AnyObject { var childCoordinators: [Coordinator] { get set } func start() diff --git a/TOASTER-iOS/Application/Coordinator/CoordinatorFinishOutput.swift b/TOASTER-iOS/Application/Coordinator/CoordinatorFinishOutput.swift index cc996c85..73d80e94 100644 --- a/TOASTER-iOS/Application/Coordinator/CoordinatorFinishOutput.swift +++ b/TOASTER-iOS/Application/Coordinator/CoordinatorFinishOutput.swift @@ -7,6 +7,7 @@ import Foundation +@MainActor protocol CoordinatorFinishOutput { var onFinish: (() -> Void)? { get set } } diff --git a/TOASTER-iOS/Application/Coordinator/Coordinators/TabBarCoordinator.swift b/TOASTER-iOS/Application/Coordinator/Coordinators/TabBarCoordinator.swift index 83a53853..9893c913 100644 --- a/TOASTER-iOS/Application/Coordinator/Coordinators/TabBarCoordinator.swift +++ b/TOASTER-iOS/Application/Coordinator/Coordinators/TabBarCoordinator.swift @@ -149,7 +149,9 @@ private extension TabBarCoordinator { accessKey: Config.accessTokenKey, refreshKey: Config.refreshTokenKey ) - self?.onFinish?() + Task { @MainActor in + self?.onFinish?() + } } } } diff --git a/TOASTER-iOS/Application/Coordinator/Factory/CoordinatorFactory.swift b/TOASTER-iOS/Application/Coordinator/Factory/CoordinatorFactory.swift index 548da376..07e909ac 100644 --- a/TOASTER-iOS/Application/Coordinator/Factory/CoordinatorFactory.swift +++ b/TOASTER-iOS/Application/Coordinator/Factory/CoordinatorFactory.swift @@ -7,6 +7,7 @@ import UIKit +@MainActor protocol CoordinatorFactoryProtocol { func makeTabBarCoordinator( router: RouterProtocol, diff --git a/TOASTER-iOS/Application/Coordinator/Factory/ViewControllerFactory.swift b/TOASTER-iOS/Application/Coordinator/Factory/ViewControllerFactory.swift index 4142f4d2..ea825848 100644 --- a/TOASTER-iOS/Application/Coordinator/Factory/ViewControllerFactory.swift +++ b/TOASTER-iOS/Application/Coordinator/Factory/ViewControllerFactory.swift @@ -7,6 +7,7 @@ import Foundation +@MainActor protocol ViewControllerFactoryProtocol { func makeLoginVC() -> LoginViewController func makeTabBarVC() -> TabBarController diff --git a/TOASTER-iOS/Application/Coordinator/Router.swift b/TOASTER-iOS/Application/Coordinator/Router.swift index 20c28cbb..4f27fbd8 100644 --- a/TOASTER-iOS/Application/Coordinator/Router.swift +++ b/TOASTER-iOS/Application/Coordinator/Router.swift @@ -7,6 +7,7 @@ import UIKit +@MainActor protocol RouterProtocol: AnyObject { func setRoot(_ viewController: UIViewController, animated: Bool) func setRoot(_ viewController: UIViewController, animated: Bool, hideBottomBarWhenPushed: Bool) diff --git a/TOASTER-iOS/Present/AddLink/View/SelectClipHeaderView.swift b/TOASTER-iOS/Present/AddLink/View/SelectClipHeaderView.swift index 15f79a01..9e20777f 100644 --- a/TOASTER-iOS/Present/AddLink/View/SelectClipHeaderView.swift +++ b/TOASTER-iOS/Present/AddLink/View/SelectClipHeaderView.swift @@ -10,6 +10,7 @@ import UIKit import SnapKit import Then +@MainActor protocol SelectClipHeaderViewlDelegate: AnyObject { func addClipCellTapped() } diff --git a/TOASTER-iOS/Present/Clip/View/Component/AddClipBottomSheetView.swift b/TOASTER-iOS/Present/Clip/View/Component/AddClipBottomSheetView.swift index 8b040fbe..716b5d80 100644 --- a/TOASTER-iOS/Present/Clip/View/Component/AddClipBottomSheetView.swift +++ b/TOASTER-iOS/Present/Clip/View/Component/AddClipBottomSheetView.swift @@ -10,6 +10,7 @@ import UIKit import SnapKit import Then +@MainActor protocol AddClipBottomSheetViewDelegate: AnyObject { func addHeightBottom() func minusHeightBottom() diff --git a/TOASTER-iOS/Present/Clip/View/Component/ClipCollectionHeaderView.swift b/TOASTER-iOS/Present/Clip/View/Component/ClipCollectionHeaderView.swift index 55df5a2a..794bd549 100644 --- a/TOASTER-iOS/Present/Clip/View/Component/ClipCollectionHeaderView.swift +++ b/TOASTER-iOS/Present/Clip/View/Component/ClipCollectionHeaderView.swift @@ -10,6 +10,7 @@ import UIKit import SnapKit import Then +@MainActor protocol ClipCollectionHeaderViewDelegate: AnyObject { func addClipButtonTapped() } diff --git a/TOASTER-iOS/Present/DetailClip/View/Cell/DetailClipListCollectionViewCell.swift b/TOASTER-iOS/Present/DetailClip/View/Cell/DetailClipListCollectionViewCell.swift index 70a33f69..3d93540f 100644 --- a/TOASTER-iOS/Present/DetailClip/View/Cell/DetailClipListCollectionViewCell.swift +++ b/TOASTER-iOS/Present/DetailClip/View/Cell/DetailClipListCollectionViewCell.swift @@ -11,6 +11,7 @@ import Kingfisher import SnapKit import Then +@MainActor protocol DetailClipListCollectionViewCellDelegate: AnyObject { func modifiedButtonTapped(toastId: Int) } diff --git a/TOASTER-iOS/Present/DetailClip/View/Component/ChangeClipBottomSheetView.swift b/TOASTER-iOS/Present/DetailClip/View/Component/ChangeClipBottomSheetView.swift index 30c8f1ee..22c07802 100644 --- a/TOASTER-iOS/Present/DetailClip/View/Component/ChangeClipBottomSheetView.swift +++ b/TOASTER-iOS/Present/DetailClip/View/Component/ChangeClipBottomSheetView.swift @@ -174,6 +174,7 @@ extension ChangeClipBottomSheetView: UICollectionViewDelegateFlowLayout { } } +@MainActor protocol ChangeClipBottomSheetViewDelegate: AnyObject { func didSelectClip(selectClipId: Int) func completButtonTap() diff --git a/TOASTER-iOS/Present/Home/View/Cell/UserClipCollectionViewCell.swift b/TOASTER-iOS/Present/Home/View/Cell/UserClipCollectionViewCell.swift index e036fa15..8a6dd3ba 100644 --- a/TOASTER-iOS/Present/Home/View/Cell/UserClipCollectionViewCell.swift +++ b/TOASTER-iOS/Present/Home/View/Cell/UserClipCollectionViewCell.swift @@ -10,6 +10,7 @@ import UIKit import SnapKit import Then +@MainActor protocol UserClipCollectionViewCellDelegate: AnyObject { func addClipCellTapped() } diff --git a/TOASTER-iOS/Present/Home/View/Component/CompositioinalFactory.swift b/TOASTER-iOS/Present/Home/View/Component/CompositioinalFactory.swift index f3219115..e1539626 100644 --- a/TOASTER-iOS/Present/Home/View/Component/CompositioinalFactory.swift +++ b/TOASTER-iOS/Present/Home/View/Component/CompositioinalFactory.swift @@ -9,6 +9,7 @@ import UIKit // MARK: - Compositional Layout +@MainActor enum CompositionalFactory { static func create() -> UICollectionViewCompositionalLayout { return UICollectionViewCompositionalLayout { (sectionNumber, _ environment) -> NSCollectionLayoutSection? in diff --git a/TOASTER-iOS/Present/Remind/View/Component/RemindAlarmOffBottomSheetView.swift b/TOASTER-iOS/Present/Remind/View/Component/RemindAlarmOffBottomSheetView.swift index 6d792753..84a7c096 100644 --- a/TOASTER-iOS/Present/Remind/View/Component/RemindAlarmOffBottomSheetView.swift +++ b/TOASTER-iOS/Present/Remind/View/Component/RemindAlarmOffBottomSheetView.swift @@ -10,6 +10,7 @@ import UIKit import SnapKit import Then +@MainActor protocol RemindAlarmOffBottomSheetViewDelegate: AnyObject { func alarmButtonTapped() } diff --git a/TOASTER-iOS/Present/Remind/View/Component/RemindTimerEditBottomSheetView.swift b/TOASTER-iOS/Present/Remind/View/Component/RemindTimerEditBottomSheetView.swift index b6dcd1f0..c82d4112 100644 --- a/TOASTER-iOS/Present/Remind/View/Component/RemindTimerEditBottomSheetView.swift +++ b/TOASTER-iOS/Present/Remind/View/Component/RemindTimerEditBottomSheetView.swift @@ -10,6 +10,7 @@ import UIKit import SnapKit import Then +@MainActor protocol RemindEditViewDelegate: AnyObject { func editTimer(forID: Int?) func deleteTimer(forID: Int?) diff --git a/TOASTER-iOS/Present/RemindAdd/TimerAdd/View/TimerRepeatBottomSheetView.swift b/TOASTER-iOS/Present/RemindAdd/TimerAdd/View/TimerRepeatBottomSheetView.swift index ac6fefd0..47e9ca62 100644 --- a/TOASTER-iOS/Present/RemindAdd/TimerAdd/View/TimerRepeatBottomSheetView.swift +++ b/TOASTER-iOS/Present/RemindAdd/TimerAdd/View/TimerRepeatBottomSheetView.swift @@ -10,6 +10,7 @@ import UIKit import SnapKit import Then +@MainActor protocol TimerRepeatBottomSheetDelegate: AnyObject { func nextButtonTapped(selectedList: Set) } diff --git a/TOASTER-iOS/Present/UpdateAlert/UpdateAlertManager.swift b/TOASTER-iOS/Present/UpdateAlert/UpdateAlertManager.swift index 77e53d4d..4476d44a 100644 --- a/TOASTER-iOS/Present/UpdateAlert/UpdateAlertManager.swift +++ b/TOASTER-iOS/Present/UpdateAlert/UpdateAlertManager.swift @@ -7,10 +7,11 @@ import UIKit -final class UpdateAlertManager { +struct UpdateAlertManager { private let appId = "6476194200" /// Alert 표출 함수 + @MainActor func showUpdateAlert(type: UpdateAlertType, on viewController: UIViewController) { let alertViewController = UIAlertController(title: type.title, From ed18f225e86da79b8ecf4bcfadc85d77ff4b2173 Mon Sep 17 00:00:00 2001 From: mini-min Date: Mon, 9 Mar 2026 20:42:37 +0900 Subject: [PATCH 3/4] =?UTF-8?q?[Refactor]=20#264=20-=20nonisolated(unsafe)?= =?UTF-8?q?=20=EC=B2=98=EB=A6=AC=20=EA=B2=BD=EA=B3=A0=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TOASTER-iOS.xcodeproj/project.pbxproj | 4 ++-- TOASTER-iOS/Global/Resources/Config.swift | 2 +- TOASTER-iOS/Network/Base/NetworkService.swift | 2 +- .../LinkWeb/ViewController/LinkWebViewController.swift | 6 ++++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/TOASTER-iOS.xcodeproj/project.pbxproj b/TOASTER-iOS.xcodeproj/project.pbxproj index 85c83e91..5083e52a 100644 --- a/TOASTER-iOS.xcodeproj/project.pbxproj +++ b/TOASTER-iOS.xcodeproj/project.pbxproj @@ -2540,7 +2540,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.2.2; + MARKETING_VERSION = 1.2.3; PRODUCT_BUNDLE_IDENTIFIER = "TeamLinkMIND.TOASTER-iOS"; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; @@ -2573,7 +2573,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.2.2; + MARKETING_VERSION = 1.2.3; PRODUCT_BUNDLE_IDENTIFIER = "TeamLinkMIND.TOASTER-iOS"; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; diff --git a/TOASTER-iOS/Global/Resources/Config.swift b/TOASTER-iOS/Global/Resources/Config.swift index ef57c0de..3bd1a37e 100644 --- a/TOASTER-iOS/Global/Resources/Config.swift +++ b/TOASTER-iOS/Global/Resources/Config.swift @@ -23,7 +23,7 @@ enum Config { } } - private static let infoDictionary: [String: Any] = { + nonisolated(unsafe) private static let infoDictionary: [String: Any] = { guard let dict = Bundle.main.infoDictionary else { fatalError("plist cannot found !!!") } diff --git a/TOASTER-iOS/Network/Base/NetworkService.swift b/TOASTER-iOS/Network/Base/NetworkService.swift index 47c7fee8..aabe5c4f 100644 --- a/TOASTER-iOS/Network/Base/NetworkService.swift +++ b/TOASTER-iOS/Network/Base/NetworkService.swift @@ -9,7 +9,7 @@ import Foundation final class NetworkService { - static let shared = NetworkService() + nonisolated(unsafe) static let shared = NetworkService() private init() {} diff --git a/TOASTER-iOS/Present/LinkWeb/ViewController/LinkWebViewController.swift b/TOASTER-iOS/Present/LinkWeb/ViewController/LinkWebViewController.swift index 19db4c19..0ef01db2 100644 --- a/TOASTER-iOS/Present/LinkWeb/ViewController/LinkWebViewController.swift +++ b/TOASTER-iOS/Present/LinkWeb/ViewController/LinkWebViewController.swift @@ -141,8 +141,10 @@ private extension LinkWebViewController { progressObservation = $0.observe( \.estimatedProgress, options: [.new]) { [weak self] object, _ in - let progress = Float(object.estimatedProgress) - self?.progressView.progress = progress + MainActor.assumeIsolated { + let progress = Float(object.estimatedProgress) + self?.progressView.progress = progress + } } } } From 4e941e6dee5c56057907c82c8cf648781d8bacd4 Mon Sep 17 00:00:00 2001 From: mini-min Date: Mon, 9 Mar 2026 22:42:41 +0900 Subject: [PATCH 4/4] =?UTF-8?q?[Refactor]=20#264=20-=20DispatchQueue=20?= =?UTF-8?q?=EA=B8=B0=EB=B0=98=20->=20Actor=20=EA=B8=B0=EB=B0=98=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TOASTER-iOS/Application/AppDelegate.swift | 64 +++++++++++-------- .../AddLink/AddLinkViewController.swift | 7 +- .../Component/ChangeClipBottomSheetView.swift | 9 ++- .../Adapter/KakaoAuthenticateAdapter.swift | 2 - .../Remind/ViewModel/RemindViewModel.swift | 4 +- 5 files changed, 49 insertions(+), 37 deletions(-) diff --git a/TOASTER-iOS/Application/AppDelegate.swift b/TOASTER-iOS/Application/AppDelegate.swift index 7861ce7e..733e6e21 100644 --- a/TOASTER-iOS/Application/AppDelegate.swift +++ b/TOASTER-iOS/Application/AppDelegate.swift @@ -34,7 +34,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { UserDefaults.standard.set(true, forKey: "isAppAlarmOn") // MARK: - 카카오 로그인 설정 - + KakaoSDK.initSDK(appKey: Config.kakaoNativeAppKey) let result = KeyChainService.loadTokens(accessKey: Config.accessTokenKey, refreshKey: Config.refreshTokenKey) @@ -50,8 +50,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate { switch loginType { case Config.appleLogin: - checkAppleLogin { [weak self] result in - self?.isLogin = result + Task { [weak self] in + let result = await self?.checkAppleLogin() ?? false + await MainActor.run { [weak self] in + self?.isLogin = result + } } case Config.kakaoLogin: checkKakaoLogin { [weak self] result in @@ -108,31 +111,34 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } } - func checkAppleLogin(completion: @escaping (Bool) -> Void) { + func checkAppleLogin() async -> Bool { let appleIDProvider = ASAuthorizationAppleIDProvider() - appleIDProvider.getCredentialState(forUserID: UserDefaults.standard.string(forKey: Config.appleUserID) ?? "") { (credentialState, error) in - switch credentialState { - case .authorized: - print("해당 ID는 연동되어있습니다.") - completion(true) - case .revoked: - print("해당 ID는 연동되어있지않습니다.") - completion(false) - case .notFound: - print("해당 ID를 찾을 수 없습니다.") - completion(false) - default: - break + return await withCheckedContinuation { continuation in + appleIDProvider.getCredentialState(forUserID: UserDefaults.standard.string(forKey: Config.appleUserID) ?? "") { credentialState, _ in + switch credentialState { + case .authorized: + print("해당 ID는 연동되어있습니다.") + continuation.resume(returning: true) + case .revoked: + print("해당 ID는 연동되어있지 않습니다.") + continuation.resume(returning: false) + case .notFound: + print("해당 ID를 찾을 수 없습니다.") + continuation.resume(returning: false) + default: + continuation.resume(returning: false) + } } } } } // MARK: - MessagingDelegate + extension AppDelegate: MessagingDelegate { // FCM 토큰을 받았을 때 실행 - func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { + nonisolated func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { if let fcmToken { let _ = KeyChainService.saveFCMToken(fcmToken: fcmToken, key: Config.fcmTokenKey) } @@ -140,16 +146,20 @@ extension AppDelegate: MessagingDelegate { } extension AppDelegate: UNUserNotificationCenterDelegate { - - func userNotificationCenter(_ center: UNUserNotificationCenter, - didReceive response: UNNotificationResponse, - withCompletionHandler completionHandler: @escaping () -> Void) { - - if let navigationViewController = UIApplication.shared.keyWindow?.rootViewController as? ToasterNavigationController { - navigationViewController.popToRootViewController(animated: false) - if let tabBarController = navigationViewController.topViewController as? TabBarController { - tabBarController.selectedIndex = 0 + nonisolated func userNotificationCenter(_ center: UNUserNotificationCenter, + didReceive response: UNNotificationResponse, + withCompletionHandler completionHandler: @escaping () -> Void) { + Task { @MainActor in + if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene, + let navigationViewController = windowScene.windows + .first(where: { $0.isKeyWindow })? + .rootViewController as? ToasterNavigationController { + navigationViewController.popToRootViewController(animated: false) + if let tabBarController = navigationViewController.topViewController as? TabBarController { + tabBarController.selectedIndex = 0 + } } } + completionHandler() } } diff --git a/TOASTER-iOS/Present/AddLink/AddLinkViewController.swift b/TOASTER-iOS/Present/AddLink/AddLinkViewController.swift index c4fed385..dfdc0f1c 100644 --- a/TOASTER-iOS/Present/AddLink/AddLinkViewController.swift +++ b/TOASTER-iOS/Present/AddLink/AddLinkViewController.swift @@ -402,8 +402,11 @@ private extension AddLinkViewController { loadingTitle: "저장 중...", loadingAnimationSize: 16, task: { _ in - DispatchQueue.global().asyncAfter(deadline: .now() + 0.5) { [weak self] in - self?.requestSaveLink.send() + Task { + try? await Task.sleep(for: .seconds(0.5)) + await MainActor.run { [weak self] in + self?.requestSaveLink.send() + } } } ) diff --git a/TOASTER-iOS/Present/DetailClip/View/Component/ChangeClipBottomSheetView.swift b/TOASTER-iOS/Present/DetailClip/View/Component/ChangeClipBottomSheetView.swift index 22c07802..15585ef2 100644 --- a/TOASTER-iOS/Present/DetailClip/View/Component/ChangeClipBottomSheetView.swift +++ b/TOASTER-iOS/Present/DetailClip/View/Component/ChangeClipBottomSheetView.swift @@ -109,9 +109,12 @@ private extension ChangeClipBottomSheetView { loadingTitle: "이동 중...", loadingAnimationSize: 16, task: { completion in - DispatchQueue.global().asyncAfter(deadline: .now() + 0.5) { - self.delegate?.completButtonTap() - completion() + Task { + try? await Task.sleep(for: .seconds(0.5)) + await MainActor.run { + self.delegate?.completButtonTap() + completion() + } } } ) diff --git a/TOASTER-iOS/Present/Login/Adapter/KakaoAuthenticateAdapter.swift b/TOASTER-iOS/Present/Login/Adapter/KakaoAuthenticateAdapter.swift index 522ad2b4..bf5c0a27 100644 --- a/TOASTER-iOS/Present/Login/Adapter/KakaoAuthenticateAdapter.swift +++ b/TOASTER-iOS/Present/Login/Adapter/KakaoAuthenticateAdapter.swift @@ -52,7 +52,6 @@ final class KakaoAuthenticateAdapter: NSObject, AuthenticationAdapterProtocol { } /// 카카오톡 간편로그인을 통해 토큰을 받아오는 메서드 - @MainActor func getLoginToken() async throws -> SocialLoginTokenModel { return try await withCheckedThrowingContinuation { continuation in UserApi.shared.loginWithKakaoTalk {(oauthToken, error) in @@ -72,7 +71,6 @@ final class KakaoAuthenticateAdapter: NSObject, AuthenticationAdapterProtocol { } /// 카카오톡 간편로그인을 할 수 없는 경우 웹에서 이메일로 로그인 해서 토큰을 받아오는 메서드 - @MainActor func getTokenKakaoAccount() async throws -> SocialLoginTokenModel { return try await withCheckedThrowingContinuation { continuation in UserApi.shared.loginWithKakaoAccount {(oauthToken, error) in diff --git a/TOASTER-iOS/Present/Remind/ViewModel/RemindViewModel.swift b/TOASTER-iOS/Present/Remind/ViewModel/RemindViewModel.swift index 674855bd..ac5e97b6 100644 --- a/TOASTER-iOS/Present/Remind/ViewModel/RemindViewModel.swift +++ b/TOASTER-iOS/Present/Remind/ViewModel/RemindViewModel.swift @@ -25,9 +25,7 @@ final class RemindViewModel { /// RemindViewType을 저장하기 위한 프로퍼티 private var remindViewType: RemindViewType = .deviceOnAppOnNoneData { didSet { - DispatchQueue.main.async { - self.dataChangeAction?(self.remindViewType) - } + self.dataChangeAction?(self.remindViewType) } }