From 737fe23925cc0794d0a29d5bb4d7ac04d7a478f5 Mon Sep 17 00:00:00 2001 From: doyeonKim Date: Mon, 14 Oct 2024 17:30:00 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20Splash=20=ED=99=94=EB=A9=B4=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=95=B1=20=EB=B2=84=EC=A0=84=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=20=EB=B0=8F=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=A0=20=EC=8B=9C=20=EC=95=B1=EC=8A=A4=ED=86=A0?= =?UTF-8?q?=EC=96=B4=EB=A1=9C=20=EB=B3=B4=EB=82=B4=EB=8A=94=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../VersionAPI/Repository/VersionAPI.swift | 38 +++++++++++++++++++ .../Repository/VersionRepository.swift | 20 ++++++++++ .../RequestDTO/VersionRequestDTO.swift | 5 +++ .../Scene/Common/SignCoordinator.swift | 8 +++- .../Scene/Common/SignDIContainer.swift | 4 +- .../Sources/Scene/Splash/SplashReactor.swift | 33 ++++++++++++---- .../Sign/Sources/Scene/Splash/SplashVC.swift | 21 ++++++++++ 7 files changed, 118 insertions(+), 11 deletions(-) create mode 100644 Projects/Core/Core/Sources/Network/APIs/VersionAPI/Repository/VersionAPI.swift create mode 100644 Projects/Core/Core/Sources/Network/APIs/VersionAPI/Repository/VersionRepository.swift create mode 100644 Projects/Core/Core/Sources/Network/APIs/VersionAPI/RequestDTO/VersionRequestDTO.swift diff --git a/Projects/Core/Core/Sources/Network/APIs/VersionAPI/Repository/VersionAPI.swift b/Projects/Core/Core/Sources/Network/APIs/VersionAPI/Repository/VersionAPI.swift new file mode 100644 index 00000000..063b452d --- /dev/null +++ b/Projects/Core/Core/Sources/Network/APIs/VersionAPI/Repository/VersionAPI.swift @@ -0,0 +1,38 @@ +import Foundation + +enum VersionAPI { + case version(VersionRequestDTO) // 버전조회 +} + +extension VersionAPI: TargetType { + var baseURL: URL? { + return try? Config.base.asURL() + } + + var path: String { + switch self { + case .version: + return "v1/version" + } + } + + var method: HTTPMethod { + switch self { + case .version: + return .post + } + } + + var task: HTTPTask { + switch self { + case let .version(param): + return .requestJSONEncodable(params: param) + } + } + + var headers: [String : String]? { + return [ + "Content-Type": "application/json;charset=UTF-8" + ] + } +} diff --git a/Projects/Core/Core/Sources/Network/APIs/VersionAPI/Repository/VersionRepository.swift b/Projects/Core/Core/Sources/Network/APIs/VersionAPI/Repository/VersionRepository.swift new file mode 100644 index 00000000..ac9c0fbd --- /dev/null +++ b/Projects/Core/Core/Sources/Network/APIs/VersionAPI/Repository/VersionRepository.swift @@ -0,0 +1,20 @@ +import Foundation + +public protocol VersionRepositoryInterface { + func get() async throws +} + +public final class VersionRepository: VersionRepositoryInterface { + private let networkManager: NetworkManagerInterfacae + + public init(networkManager: NetworkManagerInterfacae) { + self.networkManager = networkManager + } + + public func get() async throws { + if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String { + let targetType = VersionAPI.version(VersionRequestDTO(version: version)) + try await networkManager.request(target: targetType) + } + } +} diff --git a/Projects/Core/Core/Sources/Network/APIs/VersionAPI/RequestDTO/VersionRequestDTO.swift b/Projects/Core/Core/Sources/Network/APIs/VersionAPI/RequestDTO/VersionRequestDTO.swift new file mode 100644 index 00000000..dd4515a9 --- /dev/null +++ b/Projects/Core/Core/Sources/Network/APIs/VersionAPI/RequestDTO/VersionRequestDTO.swift @@ -0,0 +1,5 @@ +import Foundation + +struct VersionRequestDTO: Encodable { + let version: String +} diff --git a/Projects/Feature/Sign/Sources/Scene/Common/SignCoordinator.swift b/Projects/Feature/Sign/Sources/Scene/Common/SignCoordinator.swift index c37d6d8d..446bade2 100644 --- a/Projects/Feature/Sign/Sources/Scene/Common/SignCoordinator.swift +++ b/Projects/Feature/Sign/Sources/Scene/Common/SignCoordinator.swift @@ -54,7 +54,11 @@ public extension SignCoordinator { navigationController.popViewController(animated: animated) } - func alert(title: String) { - AlertsManager.show(title: title) + func alert(title: String, okAction: (() -> Void)? = nil) { + if let okAction { + AlertsManager.show(title: title, type: .onlyOkButton(okAction)) + } else { + AlertsManager.show(title: title) + } } } diff --git a/Projects/Feature/Sign/Sources/Scene/Common/SignDIContainer.swift b/Projects/Feature/Sign/Sources/Scene/Common/SignDIContainer.swift index c647e739..06d6c679 100644 --- a/Projects/Feature/Sign/Sources/Scene/Common/SignDIContainer.swift +++ b/Projects/Feature/Sign/Sources/Scene/Common/SignDIContainer.swift @@ -20,9 +20,11 @@ public final class SignDIContainer { kakaoAuthManager: KakaoAuthManager(), appleAuthManager: AppleAuthManager() ) + let versionRepository = VersionRepository(networkManager: networkManager) vc.reactor = SplashReactor( signRepository: signRepository, - userRepo: UserRepository(networkManager: networkManager, localStorage: localStorage) + userRepo: UserRepository(networkManager: networkManager, localStorage: localStorage), + versionRepo: versionRepository ) vc.coordinator = coordinator return vc diff --git a/Projects/Feature/Sign/Sources/Scene/Splash/SplashReactor.swift b/Projects/Feature/Sign/Sources/Scene/Splash/SplashReactor.swift index 45500094..ad6f0c4a 100644 --- a/Projects/Feature/Sign/Sources/Scene/Splash/SplashReactor.swift +++ b/Projects/Feature/Sign/Sources/Scene/Splash/SplashReactor.swift @@ -10,6 +10,7 @@ final class SplashReactor: Reactor { enum Mutation { case setDestination(Destination) + case setAlert } enum Destination { @@ -19,27 +20,41 @@ final class SplashReactor: Reactor { struct State { @Pulse var destination: Destination? + @Pulse var isUpdateAlert: Bool = false } let initialState: State = State() private let signRepository: SignRepositoryInterface private let userRepo: UserRepositoryInterface + private let versionRepo: VersionRepositoryInterface - init(signRepository: SignRepositoryInterface, userRepo: UserRepositoryInterface) { + init( + signRepository: SignRepositoryInterface, + userRepo: UserRepositoryInterface, + versionRepo: VersionRepositoryInterface + ) { self.signRepository = signRepository self.userRepo = userRepo + self.versionRepo = versionRepo } func mutate(action: Action) -> Observable { switch action { case .onAppear: - return .task { - let result = try await signRepository.autoSign() - _ = try await userRepo.user() - return result - } - .map { .setDestination($0.schoolInfoProvided ? .main : .login) } - .catch { _ in .just(.setDestination(.login)) } + .task { + try await versionRepo.get() + let result = try await signRepository.autoSign() + _ = try await userRepo.user() + return result + } + .map { .setDestination($0.schoolInfoProvided ? .main : .login) } + .catch { error in + if error.localizedDescription == "앱 업데이트가 필요합니다." { + return .just(.setAlert) + } else { + return .just(.setDestination(.login)) + } + } } } @@ -48,6 +63,8 @@ final class SplashReactor: Reactor { switch mutation { case .setDestination(let destination): newState.destination = destination + case .setAlert: + newState.isUpdateAlert = true } return newState } diff --git a/Projects/Feature/Sign/Sources/Scene/Splash/SplashVC.swift b/Projects/Feature/Sign/Sources/Scene/Splash/SplashVC.swift index 5b5ec9a9..aa8dc3dc 100644 --- a/Projects/Feature/Sign/Sources/Scene/Splash/SplashVC.swift +++ b/Projects/Feature/Sign/Sources/Scene/Splash/SplashVC.swift @@ -50,6 +50,27 @@ final class SplashVC: BaseVC, View { } } .disposed(by: disposeBag) + + reactor.pulse(\.$isUpdateAlert) + .observe(on: MainScheduler.instance) + .filter { $0 } + .bind(with: self) { owner, value in + owner.coordinator?.alert(title: "안정적인 머니몽 사용을 위해\n최신 버전으로 업데이트가 필요해요!") { + if let url = URL(string: "itms-apps://itunes.apple.com/app/id6503661220"), + UIApplication.shared.canOpenURL(url) + { + UIApplication.shared.open(url) { result in + if result { + UIApplication.shared.perform(#selector(NSXPCConnection.suspend)) + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { + exit(0) + } + } + } + } + } + } + .disposed(by: disposeBag) rx.viewDidAppear .delay(.milliseconds(500), scheduler: MainScheduler.instance)