From 85f58f348e0e1939f3b2d3e16444010f0bfdfe25 Mon Sep 17 00:00:00 2001 From: soonny <134983918+soeun11@users.noreply.github.com> Date: Fri, 19 Jun 2026 23:49:42 +0900 Subject: [PATCH 1/6] =?UTF-8?q?[network]=ED=83=88=ED=87=B4=ED=95=98?= =?UTF-8?q?=EA=B8=B0,=20=EB=A1=9C=EA=B7=B8=EC=95=84=EC=9B=83=20api=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/DTO/Auth/LogoutRequestDTO.swift | 16 +++++++++++ .../Sources/DTO/Auth/WithdrawRequestDTO.swift | 14 ++++++++++ .../Data/Sources/DTO/Base/BaseResponse.swift | 4 +-- .../Data/Sources/Networking/API/AuthAPI.swift | 14 +++++++--- .../Networking/Service/AuthService.swift | 21 ++++++++++++-- .../RepositoryImpl/AuthRepositoryImpl.swift | 8 ++++-- .../Sources/Repository/AuthRepository.swift | 3 +- .../Sources/UseCase/Auth/LogoutUseCase.swift | 28 +++++++++++++++++++ .../UseCase/Auth/WithDrawUseCase.swift | 6 ++-- FLINT/FLINT/Dependency/DIContainer.swift | 3 ++ .../UseCase/Auth/LogoutUseCaseFactory..swift | 20 +++++++++++++ .../SettingViewControllerFactory+.swift | 19 +++++++++++++ .../WithdrawalViewControllerFactory+.swift | 19 +++++++++++++ .../ViewModel/SettingViewModelFactory.swift | 20 +++++++++++++ .../ViewModel/WithdrawViewModelFactory.swift | 19 +++++++++++++ .../Dependency/ViewControllerFactory.swift | 4 ++- .../Scene/Setting/SettingViewController.swift | 3 +- .../WithdrawViewController.swift | 22 +++++++++++---- .../Scene/Setting/SettingViewModel.swift | 23 +++++++++++---- .../Sources/ViewModel/WithdrawViewModel.swift | 23 ++++++++------- 20 files changed, 250 insertions(+), 39 deletions(-) create mode 100644 FLINT/Data/Sources/DTO/Auth/LogoutRequestDTO.swift create mode 100644 FLINT/Data/Sources/DTO/Auth/WithdrawRequestDTO.swift create mode 100644 FLINT/Domain/Sources/UseCase/Auth/LogoutUseCase.swift create mode 100644 FLINT/FLINT/Dependency/Factory/UseCase/Auth/LogoutUseCaseFactory..swift create mode 100644 FLINT/FLINT/Dependency/Factory/ViewController/SettingViewControllerFactory+.swift create mode 100644 FLINT/FLINT/Dependency/Factory/ViewController/WithdrawalViewControllerFactory+.swift create mode 100644 FLINT/FLINT/Dependency/Factory/ViewModel/SettingViewModelFactory.swift create mode 100644 FLINT/FLINT/Dependency/Factory/ViewModel/WithdrawViewModelFactory.swift diff --git a/FLINT/Data/Sources/DTO/Auth/LogoutRequestDTO.swift b/FLINT/Data/Sources/DTO/Auth/LogoutRequestDTO.swift new file mode 100644 index 00000000..6ed99095 --- /dev/null +++ b/FLINT/Data/Sources/DTO/Auth/LogoutRequestDTO.swift @@ -0,0 +1,16 @@ +// +// LogoutRequestDTO.swift +// Data +// +// Created by 소은 on 6/19/26. +// + +import Foundation + +public struct LogoutRequestDTO: Encodable { + public let refreshToken: String + + public init(refreshToken: String) { + self.refreshToken = refreshToken + } +} diff --git a/FLINT/Data/Sources/DTO/Auth/WithdrawRequestDTO.swift b/FLINT/Data/Sources/DTO/Auth/WithdrawRequestDTO.swift new file mode 100644 index 00000000..992d2e40 --- /dev/null +++ b/FLINT/Data/Sources/DTO/Auth/WithdrawRequestDTO.swift @@ -0,0 +1,14 @@ +// +// WithdrawRequestDTO.swift +// Data +// + +import Foundation + +public struct WithdrawRequestDTO: Encodable { + public let agreedTermsIds: [String] + + public init(agreedTermsIds: [String]) { + self.agreedTermsIds = agreedTermsIds + } +} diff --git a/FLINT/Data/Sources/DTO/Base/BaseResponse.swift b/FLINT/Data/Sources/DTO/Base/BaseResponse.swift index cd097c8a..3a1832df 100644 --- a/FLINT/Data/Sources/DTO/Base/BaseResponse.swift +++ b/FLINT/Data/Sources/DTO/Base/BaseResponse.swift @@ -19,7 +19,7 @@ public struct BaseResponse: Codable { public let additionalInfo: [String: String]? public let status: Int - public let message: String + public let message: String? public let data: T? } @@ -36,7 +36,7 @@ extension BaseResponse { errorCode: errorCode ?? "", additionalInfo: additionalInfo ?? [:], status: status, - message: message + message: message ?? "" ) } } diff --git a/FLINT/Data/Sources/Networking/API/AuthAPI.swift b/FLINT/Data/Sources/Networking/API/AuthAPI.swift index 1f28956c..9f38f3d9 100644 --- a/FLINT/Data/Sources/Networking/API/AuthAPI.swift +++ b/FLINT/Data/Sources/Networking/API/AuthAPI.swift @@ -12,12 +12,12 @@ import Moya import DTO public enum AuthAPI { - case logout + case logout(refreshToken: String) case logoutAll case refresh case signup(userInfo: SignupRequestDTO) case socialVerify(socialAuthCredential: SocialVerifyRequestDTO) - case withdraw + case withdraw(agreedTermsIds: [String]) } extension AuthAPI: TargetType { @@ -25,7 +25,9 @@ extension AuthAPI: TargetType { switch self { case .signup: return "/api/v1/auth/signup" - case .logout, .logoutAll, .refresh: + case .logout: + return "/api/v1/auth/logout" + case .logoutAll, .refresh: #warning("TODO: - 나중에 구현할 것") return "TODO" case .socialVerify: @@ -50,8 +52,12 @@ extension AuthAPI: TargetType { return .requestJSONEncodable(userInfo) case let .socialVerify(socialAuthCredential): return .requestJSONEncodable(socialAuthCredential) - case .logout, .logoutAll, .refresh, .withdraw: + case let .logout(refreshToken): + return .requestJSONEncodable(LogoutRequestDTO(refreshToken: refreshToken)) + case .logoutAll, .refresh: return .requestPlain + case let .withdraw(agreedTermsIds): + return .requestJSONEncodable(WithdrawRequestDTO(agreedTermsIds: agreedTermsIds)) } } } diff --git a/FLINT/Data/Sources/Networking/Service/AuthService.swift b/FLINT/Data/Sources/Networking/Service/AuthService.swift index be999c37..8f36f3a7 100644 --- a/FLINT/Data/Sources/Networking/Service/AuthService.swift +++ b/FLINT/Data/Sources/Networking/Service/AuthService.swift @@ -18,7 +18,8 @@ import DTO public protocol AuthService { func signup(userInfo: SignupInfoEntity) -> AnyPublisher func socialVerify(socialAuthCredential: SocialVerifyRequestDTO) -> AnyPublisher - func withDraw() -> AnyPublisher + func logout() -> AnyPublisher + func withDraw(agreedTermsIds: [String]) -> AnyPublisher } public final class DefaultAuthService: AuthService { @@ -67,8 +68,22 @@ public final class DefaultAuthService: AuthService { .eraseToAnyPublisher() } - public func withDraw() -> AnyPublisher { - authAPIProvider.requestPublisher(.withdraw) + public func logout() -> AnyPublisher { + guard let refreshToken = tokenStorage.load(type: .refreshToken) else { + return Fail(error: TokenError.noToken).eraseToAnyPublisher() + } + return authAPIProvider.requestPublisher(.logout(refreshToken: refreshToken)) + .logged() + .mapBaseResponseData(BlankData.self) + .map({ [weak self] _ in + self?.tokenStorage.clearAll() + }) + .eraseToAnyPublisher() + } + + public func withDraw(agreedTermsIds: [String]) -> AnyPublisher { + return authAPIProvider.requestPublisher(.withdraw(agreedTermsIds: agreedTermsIds)) + .logged() .mapBaseResponseData(BlankData.self) .map({ _ in }) .eraseToAnyPublisher() diff --git a/FLINT/Data/Sources/RepositoryImpl/AuthRepositoryImpl.swift b/FLINT/Data/Sources/RepositoryImpl/AuthRepositoryImpl.swift index c7647ec8..b61f3863 100644 --- a/FLINT/Data/Sources/RepositoryImpl/AuthRepositoryImpl.swift +++ b/FLINT/Data/Sources/RepositoryImpl/AuthRepositoryImpl.swift @@ -33,7 +33,11 @@ public final class DefaultAuthRepository: AuthRepository { .eraseToAnyPublisher() } - public func withDraw() -> AnyPublisher { - return authService.withDraw() + public func logout() -> AnyPublisher { + return authService.logout() + } + + public func withDraw(agreedTermsIds: [String]) -> AnyPublisher { + return authService.withDraw(agreedTermsIds: agreedTermsIds) } } diff --git a/FLINT/Domain/Sources/Repository/AuthRepository.swift b/FLINT/Domain/Sources/Repository/AuthRepository.swift index 7ab15d08..52ccf0a6 100644 --- a/FLINT/Domain/Sources/Repository/AuthRepository.swift +++ b/FLINT/Domain/Sources/Repository/AuthRepository.swift @@ -13,5 +13,6 @@ import Entity public protocol AuthRepository { func signup(userInfo: SignupInfoEntity) -> AnyPublisher func socialVerify(socialAuthCredential: SocialVerifyEntity) -> AnyPublisher - func withDraw() -> AnyPublisher + func logout() -> AnyPublisher + func withDraw(agreedTermsIds: [String]) -> AnyPublisher } diff --git a/FLINT/Domain/Sources/UseCase/Auth/LogoutUseCase.swift b/FLINT/Domain/Sources/UseCase/Auth/LogoutUseCase.swift new file mode 100644 index 00000000..6880c3d7 --- /dev/null +++ b/FLINT/Domain/Sources/UseCase/Auth/LogoutUseCase.swift @@ -0,0 +1,28 @@ +// +// LogoutUseCase.swift +// Domain +// +// Created by 소은 on 6/19/26. +// + +import Combine +import Foundation + +import Repository + +public protocol LogoutUseCase { + func callAsFunction() -> AnyPublisher +} + +public final class DefaultLogoutUseCase: LogoutUseCase { + + private let authRepository: AuthRepository + + public init(authRepository: AuthRepository) { + self.authRepository = authRepository + } + + public func callAsFunction() -> AnyPublisher { + return authRepository.logout() + } +} diff --git a/FLINT/Domain/Sources/UseCase/Auth/WithDrawUseCase.swift b/FLINT/Domain/Sources/UseCase/Auth/WithDrawUseCase.swift index afe2fdec..0c27fc9f 100644 --- a/FLINT/Domain/Sources/UseCase/Auth/WithDrawUseCase.swift +++ b/FLINT/Domain/Sources/UseCase/Auth/WithDrawUseCase.swift @@ -12,7 +12,7 @@ import Entity import Repository public protocol WithDrawUseCase { - func callAsFunction() -> AnyPublisher + func callAsFunction(agreedTermsIds: [String]) -> AnyPublisher } public final class DefaultWithDrawUseCase: WithDrawUseCase { @@ -23,7 +23,7 @@ public final class DefaultWithDrawUseCase: WithDrawUseCase { self.authRepository = authRepository } - public func callAsFunction() -> AnyPublisher { - return authRepository.withDraw() + public func callAsFunction(agreedTermsIds: [String]) -> AnyPublisher { + return authRepository.withDraw(agreedTermsIds: agreedTermsIds) } } diff --git a/FLINT/FLINT/Dependency/DIContainer.swift b/FLINT/FLINT/Dependency/DIContainer.swift index 4c842490..30beb40b 100644 --- a/FLINT/FLINT/Dependency/DIContainer.swift +++ b/FLINT/FLINT/Dependency/DIContainer.swift @@ -24,6 +24,9 @@ typealias DependencyFactory = ViewControllerFactory & ExploreViewModelFactory & ProfileViewModelFactory & + SettingViewModelFactory & + WithdrawViewModelFactory & + CreateCollectionViewModelFactory & AddContentSelectViewModelFactory & CollectionFolderListViewModelFactory & diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/Auth/LogoutUseCaseFactory..swift b/FLINT/FLINT/Dependency/Factory/UseCase/Auth/LogoutUseCaseFactory..swift new file mode 100644 index 00000000..4c094e68 --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/UseCase/Auth/LogoutUseCaseFactory..swift @@ -0,0 +1,20 @@ +// +// LogoutUseCaseFactory..swift +// FLINT +// +// Created by 소은 on 6/19/26. +// + +import Foundation + +import Domain + +protocol LogoutUseCaseFactory: AuthRepositoryFactory { + func makeLogoutUseCase() -> LogoutUseCase +} + +extension LogoutUseCaseFactory { + func makeLogoutUseCase() -> LogoutUseCase { + return DefaultLogoutUseCase(authRepository: makeAuthRepository()) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/ViewController/SettingViewControllerFactory+.swift b/FLINT/FLINT/Dependency/Factory/ViewController/SettingViewControllerFactory+.swift new file mode 100644 index 00000000..a45bd3df --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/ViewController/SettingViewControllerFactory+.swift @@ -0,0 +1,19 @@ +// +// SettingViewControllerFactory+.swift +// FLINT +// +// Created by 소은 on 6/19/26. +// + +import Foundation + +import Presentation + +extension SettingViewControllerFactory where Self: SettingViewModelFactory & ViewControllerFactory { + func makeSettingViewController() -> SettingViewController { + return SettingViewController( + settingViewModel: makeSettingViewModel(), + viewControllerFactory: self + ) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/ViewController/WithdrawalViewControllerFactory+.swift b/FLINT/FLINT/Dependency/Factory/ViewController/WithdrawalViewControllerFactory+.swift new file mode 100644 index 00000000..0134366a --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/ViewController/WithdrawalViewControllerFactory+.swift @@ -0,0 +1,19 @@ +// +// WithdrawalViewControllerFactory+.swift +// FLINT +// +// Created by 소은 on 6/19/26. +// + +import Foundation + +import Presentation + +extension WithdrawalViewControllerFactory where Self: WithdrawViewModelFactory & ViewControllerFactory { + func makeWithdrawalViewController() -> WithdrawalViewController { + return WithdrawalViewController( + viewModel: makeWithdrawViewModel(), + viewControllerFactory: self + ) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/ViewModel/SettingViewModelFactory.swift b/FLINT/FLINT/Dependency/Factory/ViewModel/SettingViewModelFactory.swift new file mode 100644 index 00000000..4c952200 --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/ViewModel/SettingViewModelFactory.swift @@ -0,0 +1,20 @@ +// +// SettingViewModelFactory.swift +// FLINT +// +// Created by 소은 on 6/19/26. +// + +import Foundation + +import Presentation + +protocol SettingViewModelFactory: LogoutUseCaseFactory { + func makeSettingViewModel() -> any SettingViewModel +} + +extension SettingViewModelFactory { + func makeSettingViewModel() -> any SettingViewModel { + return DefaultSettingViewModel(logoutUseCase: makeLogoutUseCase()) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/ViewModel/WithdrawViewModelFactory.swift b/FLINT/FLINT/Dependency/Factory/ViewModel/WithdrawViewModelFactory.swift new file mode 100644 index 00000000..263b066b --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/ViewModel/WithdrawViewModelFactory.swift @@ -0,0 +1,19 @@ +// +// WithdrawViewModelFactory.swift +// FLINT +// +// Created by 소은 on 6/19/26. +// + +import Foundation +import Presentation + +protocol WithdrawViewModelFactory: WithDrawUseCaseFactory { + func makeWithdrawViewModel() -> WithdrawViewModel +} + +extension WithdrawViewModelFactory { + func makeWithdrawViewModel() -> WithdrawViewModel { + return WithdrawViewModel(withDrawUseCase: makeWithDrawUseCase()) + } +} diff --git a/FLINT/Presentation/Sources/ViewController/Dependency/ViewControllerFactory.swift b/FLINT/Presentation/Sources/ViewController/Dependency/ViewControllerFactory.swift index 7b5b09ac..67814ccc 100644 --- a/FLINT/Presentation/Sources/ViewController/Dependency/ViewControllerFactory.swift +++ b/FLINT/Presentation/Sources/ViewController/Dependency/ViewControllerFactory.swift @@ -35,4 +35,6 @@ public typealias ViewControllerFactory = CollectionFolderListViewControllerFactory & CollectionDetailViewControllerFactory & AddContentSelectViewControllerFactory & - CreateCollectionViewControllerFactory + CreateCollectionViewControllerFactory & + SettingViewControllerFactory & + WithdrawalViewControllerFactory diff --git a/FLINT/Presentation/Sources/ViewController/Scene/Setting/SettingViewController.swift b/FLINT/Presentation/Sources/ViewController/Scene/Setting/SettingViewController.swift index d189c45c..527ee355 100644 --- a/FLINT/Presentation/Sources/ViewController/Scene/Setting/SettingViewController.swift +++ b/FLINT/Presentation/Sources/ViewController/Scene/Setting/SettingViewController.swift @@ -314,7 +314,8 @@ private extension SettingViewController { } func showWithdrawalAlert() { - print("Navigate to Withdrawal Page") + guard let vc = viewControllerFactory?.makeWithdrawalViewController() else { return } + navigationController?.pushViewController(vc, animated: true) } func handleLogoutSuccess() { diff --git a/FLINT/Presentation/Sources/ViewController/WithdrawViewController.swift b/FLINT/Presentation/Sources/ViewController/WithdrawViewController.swift index 6b1b2c62..58f1f2ad 100644 --- a/FLINT/Presentation/Sources/ViewController/WithdrawViewController.swift +++ b/FLINT/Presentation/Sources/ViewController/WithdrawViewController.swift @@ -12,6 +12,10 @@ import Combine import View import ViewModel +public protocol WithdrawalViewControllerFactory { + func makeWithdrawalViewController() -> WithdrawalViewController +} + public final class WithdrawalViewController: BaseViewController { // MARK: - Property @@ -23,10 +27,9 @@ public final class WithdrawalViewController: BaseViewController // MARK: - Init - public init(viewModel: WithdrawViewModel) { + public init(viewModel: WithdrawViewModel, viewControllerFactory: (any ViewControllerFactory)?) { self.viewModel = viewModel - // FIXME: viewControllerFactory 주입해주기 - super.init(viewControllerFactory: nil) + super.init(viewControllerFactory: viewControllerFactory) } required init?(coder: NSCoder) { @@ -65,8 +68,15 @@ public final class WithdrawalViewController: BaseViewController output.withdrawSuccess .receive(on: DispatchQueue.main) .sink { [weak self] _ in - print("탈퇴 성공") - self?.navigationController?.popViewController(animated: true) + guard let self else { return } + guard let loginVC = viewControllerFactory?.makeLoginViewController() else { return } + let nav = UINavigationController(rootViewController: loginVC) + nav.modalPresentationStyle = .fullScreen + if let window = view.window { + UIView.transition(with: window, duration: 0.3, options: .transitionCrossDissolve) { + window.rootViewController = nav + } + } } .store(in: &cancellables) @@ -78,7 +88,7 @@ public final class WithdrawalViewController: BaseViewController .store(in: &cancellables) } - // MARK: - Setup + // MARK: - Setup private func setupNavigationBar() { setNavigationBar(.init( diff --git a/FLINT/Presentation/Sources/ViewModel/Scene/Setting/SettingViewModel.swift b/FLINT/Presentation/Sources/ViewModel/Scene/Setting/SettingViewModel.swift index 6ce10397..c813e5e9 100644 --- a/FLINT/Presentation/Sources/ViewModel/Scene/Setting/SettingViewModel.swift +++ b/FLINT/Presentation/Sources/ViewModel/Scene/Setting/SettingViewModel.swift @@ -55,12 +55,13 @@ public final class DefaultSettingViewModel: SettingViewModel { // MARK: - Properties + private let logoutUseCase: LogoutUseCase private var cancellables: Set = Set() // MARK: - Initialization - public init() { - // TODO: UseCase 주입 + public init(logoutUseCase: LogoutUseCase) { + self.logoutUseCase = logoutUseCase fetchUserProfile() } @@ -91,8 +92,19 @@ public final class DefaultSettingViewModel: SettingViewModel { } public func performLogout() { - // TODO: UseCase 연결 - logoutSuccess.send() + logoutUseCase() + .receive(on: DispatchQueue.main) + .sink( + receiveCompletion: { completion in + if case .failure(let error) = completion { + print("로그아웃 실패: \(error)") + } + }, + receiveValue: { [weak self] in + self?.logoutSuccess.send() + } + ) + .store(in: &cancellables) } public func performWithdrawal() { @@ -103,12 +115,11 @@ public final class DefaultSettingViewModel: SettingViewModel { // MARK: - Private Methods private func fetchUserProfile() { - // 임시 Mock 데이터 let mockProfile = UserProfileEntity( id: "user123", nickname: "플리니", profileImageUrl: nil, - role: .fliner + role: .fliner ) userProfile.send(mockProfile) } diff --git a/FLINT/Presentation/Sources/ViewModel/WithdrawViewModel.swift b/FLINT/Presentation/Sources/ViewModel/WithdrawViewModel.swift index 2941606b..689d5b98 100644 --- a/FLINT/Presentation/Sources/ViewModel/WithdrawViewModel.swift +++ b/FLINT/Presentation/Sources/ViewModel/WithdrawViewModel.swift @@ -5,19 +5,23 @@ // Created by 소은 on 5/13/26. // - import Foundation import Combine +import Domain + public final class WithdrawViewModel { - + // MARK: - Property - + + private let withDrawUseCase: WithDrawUseCase private var cancellables = Set() - + // MARK: - Init - - public init() {} + + public init(withDrawUseCase: WithDrawUseCase) { + self.withDrawUseCase = withDrawUseCase + } // MARK: - Input @@ -85,10 +89,9 @@ public final class WithdrawViewModel { // MARK: - Custom Method private func withdraw() -> AnyPublisher, Never> { - // TODO: UseCase 호출 - - // 임시 구현 - return Just(Result.success(())) + return withDrawUseCase(agreedTermsIds: ["10"]) + .map { Result.success($0) } + .catch { Just(Result.failure($0)) } .eraseToAnyPublisher() } } From ba1d130fade02e7dd3ce815ddde91020fb2ec843 Mon Sep 17 00:00:00 2001 From: soonny <134983918+soeun11@users.noreply.github.com> Date: Fri, 19 Jun 2026 23:53:34 +0900 Subject: [PATCH 2/6] =?UTF-8?q?[chore]=20TODO=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/ViewModel/Scene/Setting/SettingViewModel.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/FLINT/Presentation/Sources/ViewModel/Scene/Setting/SettingViewModel.swift b/FLINT/Presentation/Sources/ViewModel/Scene/Setting/SettingViewModel.swift index c813e5e9..87b7cda2 100644 --- a/FLINT/Presentation/Sources/ViewModel/Scene/Setting/SettingViewModel.swift +++ b/FLINT/Presentation/Sources/ViewModel/Scene/Setting/SettingViewModel.swift @@ -108,7 +108,6 @@ public final class DefaultSettingViewModel: SettingViewModel { } public func performWithdrawal() { - // TODO: 탈퇴 UseCase 연결 print("회원탈퇴") } From 9fa906156bf0e7c8c8b415b743e9515179ca8ad2 Mon Sep 17 00:00:00 2001 From: soonny <134983918+soeun11@users.noreply.github.com> Date: Sun, 21 Jun 2026 02:27:35 +0900 Subject: [PATCH 3/6] =?UTF-8?q?[network]=20=EC=8B=A0=EA=B3=A0=ED=95=98?= =?UTF-8?q?=EA=B8=B0=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Data/Sources/DTO/Base/BaseResponse.swift | 4 +- .../DTO/Collection/ReportRequestDTO.swift | 16 ++++++ .../Networking/API/CollectionAPI.swift | 17 +++--- .../Service/CollectionService.swift | 8 +++ .../CollectionRepositoryImpl.swift | 4 ++ .../Repository/CollectionRepository.swift | 1 + .../Collection/ReportCollectionUseCase.swift | 28 +++++++++ FLINT/FLINT/Dependency/DIContainer.swift | 2 + .../ReportCollectionUseCaseFactory.swift | 20 +++++++ .../ReportViewControllerFactory+.swift | 17 ++++++ .../ViewModel/ReportViewModelFactory.swift | 20 +++++++ .../Dependency/ViewControllerFactory.swift | 5 +- .../ViewController/ReportViewController.swift | 28 +++++---- .../TermsAgreementViewController.swift | 4 +- .../Sources/ViewModel/ReportViewModel.swift | 57 ++++++++----------- 15 files changed, 174 insertions(+), 57 deletions(-) create mode 100644 FLINT/Data/Sources/DTO/Collection/ReportRequestDTO.swift create mode 100644 FLINT/Domain/Sources/UseCase/Collection/ReportCollectionUseCase.swift create mode 100644 FLINT/FLINT/Dependency/Factory/UseCase/Collection/ReportCollectionUseCaseFactory.swift create mode 100644 FLINT/FLINT/Dependency/Factory/ViewController/ReportViewControllerFactory+.swift create mode 100644 FLINT/FLINT/Dependency/Factory/ViewModel/ReportViewModelFactory.swift diff --git a/FLINT/Data/Sources/DTO/Base/BaseResponse.swift b/FLINT/Data/Sources/DTO/Base/BaseResponse.swift index cd097c8a..3a1832df 100644 --- a/FLINT/Data/Sources/DTO/Base/BaseResponse.swift +++ b/FLINT/Data/Sources/DTO/Base/BaseResponse.swift @@ -19,7 +19,7 @@ public struct BaseResponse: Codable { public let additionalInfo: [String: String]? public let status: Int - public let message: String + public let message: String? public let data: T? } @@ -36,7 +36,7 @@ extension BaseResponse { errorCode: errorCode ?? "", additionalInfo: additionalInfo ?? [:], status: status, - message: message + message: message ?? "" ) } } diff --git a/FLINT/Data/Sources/DTO/Collection/ReportRequestDTO.swift b/FLINT/Data/Sources/DTO/Collection/ReportRequestDTO.swift new file mode 100644 index 00000000..e4a4130a --- /dev/null +++ b/FLINT/Data/Sources/DTO/Collection/ReportRequestDTO.swift @@ -0,0 +1,16 @@ +// +// ReportRequestDTO.swift +// Data +// + +import Foundation + +public struct ReportRequestDTO: Encodable { + public let reasons: [String] + public let otherDetail: String? + + public init(reasons: [String], otherDetail: String?) { + self.reasons = reasons + self.otherDetail = otherDetail + } +} diff --git a/FLINT/Data/Sources/Networking/API/CollectionAPI.swift b/FLINT/Data/Sources/Networking/API/CollectionAPI.swift index 01e41785..afa68cc6 100644 --- a/FLINT/Data/Sources/Networking/API/CollectionAPI.swift +++ b/FLINT/Data/Sources/Networking/API/CollectionAPI.swift @@ -10,12 +10,14 @@ import Foundation import Moya import Domain +import DTO public enum CollectionAPI { case fetchCollections(cursor: Int64?, size: Int32) case createCollection(collectionInfo: CreateCollectionEntity) case fetchCollectionDetail(collectionId: Int64) case fetchRecentViewedCollections + case reportCollection(collectionId: Int64, reasons: [String], otherDetail: String?) } extension CollectionAPI: TargetType { @@ -27,6 +29,8 @@ extension CollectionAPI: TargetType { return "/api/v1/collections/\(collectionId)" case .fetchRecentViewedCollections: return "/api/v1/collections/recent" + case let .reportCollection(collectionId, _, _): + return "/api/v1/collections/\(collectionId)/reports" } } @@ -34,7 +38,7 @@ extension CollectionAPI: TargetType { switch self { case .fetchCollections, .fetchCollectionDetail, .fetchRecentViewedCollections: return .get - case .createCollection: + case .createCollection, .reportCollection: return .post } } @@ -42,20 +46,17 @@ extension CollectionAPI: TargetType { public var task: Moya.Task { switch self { case let .fetchCollections(cursor, size): - var parameters: [String: Any] = [ - "size": size, - ] + var parameters: [String: Any] = ["size": size] if let cursor { parameters["cursor"] = cursor } - return .requestParameters( - parameters: parameters, - encoding: URLEncoding.queryString - ) + return .requestParameters(parameters: parameters, encoding: URLEncoding.queryString) case let .createCollection(collectionInfo): return .requestJSONEncodable(collectionInfo) case .fetchCollectionDetail, .fetchRecentViewedCollections: return .requestPlain + case let .reportCollection(_, reasons, otherDetail): + return .requestJSONEncodable(ReportRequestDTO(reasons: reasons, otherDetail: otherDetail)) } } } diff --git a/FLINT/Data/Sources/Networking/Service/CollectionService.swift b/FLINT/Data/Sources/Networking/Service/CollectionService.swift index 0e4c26d8..612281c4 100644 --- a/FLINT/Data/Sources/Networking/Service/CollectionService.swift +++ b/FLINT/Data/Sources/Networking/Service/CollectionService.swift @@ -20,6 +20,7 @@ public protocol CollectionService { func createCollection(collectionInfo: CreateCollectionEntity) -> AnyPublisher func fetchCollectionDetail(collectionId: Int64) -> AnyPublisher func fetchRecentViewedCollections() -> AnyPublisher + func reportCollection(collectionId: Int64, reasons: [String], otherDetail: String?) -> AnyPublisher } public final class DefaultCollectionService: CollectionService { @@ -48,4 +49,11 @@ public final class DefaultCollectionService: CollectionService { return collectionAPIProvider.requestPublisher(.fetchRecentViewedCollections) .mapBaseResponseData(CollectionsDTO.self) } + + public func reportCollection(collectionId: Int64, reasons: [String], otherDetail: String?) -> AnyPublisher { + return collectionAPIProvider.requestPublisher(.reportCollection(collectionId: collectionId, reasons: reasons, otherDetail: otherDetail)) + .mapBaseResponseData(BlankData.self) + .map { _ in } + .eraseToAnyPublisher() + } } diff --git a/FLINT/Data/Sources/RepositoryImpl/CollectionRepositoryImpl.swift b/FLINT/Data/Sources/RepositoryImpl/CollectionRepositoryImpl.swift index be2dd5ca..187a1500 100644 --- a/FLINT/Data/Sources/RepositoryImpl/CollectionRepositoryImpl.swift +++ b/FLINT/Data/Sources/RepositoryImpl/CollectionRepositoryImpl.swift @@ -44,4 +44,8 @@ public final class DefaultCollectionRepository: CollectionRepository { .tryMap { try $0.entities } .eraseToAnyPublisher() } + + public func reportCollection(collectionId: Int64, reasons: [String], otherDetail: String?) -> AnyPublisher { + return collectionService.reportCollection(collectionId: collectionId, reasons: reasons, otherDetail: otherDetail) + } } diff --git a/FLINT/Domain/Sources/Repository/CollectionRepository.swift b/FLINT/Domain/Sources/Repository/CollectionRepository.swift index 8d60e639..4b4af4d1 100644 --- a/FLINT/Domain/Sources/Repository/CollectionRepository.swift +++ b/FLINT/Domain/Sources/Repository/CollectionRepository.swift @@ -15,4 +15,5 @@ public protocol CollectionRepository { func createCollection(collectionInfo: CreateCollectionEntity) -> AnyPublisher func fetchCollectionDetail(collectionId: Int64) -> AnyPublisher func fetchRecentViewedCollections() -> AnyPublisher<[CollectionEntity], Error> + func reportCollection(collectionId: Int64, reasons: [String], otherDetail: String?) -> AnyPublisher } diff --git a/FLINT/Domain/Sources/UseCase/Collection/ReportCollectionUseCase.swift b/FLINT/Domain/Sources/UseCase/Collection/ReportCollectionUseCase.swift new file mode 100644 index 00000000..b449c37a --- /dev/null +++ b/FLINT/Domain/Sources/UseCase/Collection/ReportCollectionUseCase.swift @@ -0,0 +1,28 @@ +// +// ReportCollectionUseCase.swift +// Domain +// +// Created by 소은 on 6/21/26. +// + +import Combine +import Foundation + +import Repository + +public protocol ReportCollectionUseCase { + func callAsFunction(collectionId: Int64, reasons: [String], otherDetail: String?) -> AnyPublisher +} + +public final class DefaultReportCollectionUseCase: ReportCollectionUseCase { + + private let collectionRepository: CollectionRepository + + public init(collectionRepository: CollectionRepository) { + self.collectionRepository = collectionRepository + } + + public func callAsFunction(collectionId: Int64, reasons: [String], otherDetail: String?) -> AnyPublisher { + return collectionRepository.reportCollection(collectionId: collectionId, reasons: reasons, otherDetail: otherDetail) + } +} diff --git a/FLINT/FLINT/Dependency/DIContainer.swift b/FLINT/FLINT/Dependency/DIContainer.swift index 4c842490..73b25ea2 100644 --- a/FLINT/FLINT/Dependency/DIContainer.swift +++ b/FLINT/FLINT/Dependency/DIContainer.swift @@ -24,6 +24,8 @@ typealias DependencyFactory = ViewControllerFactory & ExploreViewModelFactory & ProfileViewModelFactory & + ReportViewModelFactory & + CreateCollectionViewModelFactory & AddContentSelectViewModelFactory & CollectionFolderListViewModelFactory & diff --git a/FLINT/FLINT/Dependency/Factory/UseCase/Collection/ReportCollectionUseCaseFactory.swift b/FLINT/FLINT/Dependency/Factory/UseCase/Collection/ReportCollectionUseCaseFactory.swift new file mode 100644 index 00000000..9b5fe553 --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/UseCase/Collection/ReportCollectionUseCaseFactory.swift @@ -0,0 +1,20 @@ +// +// ReportCollectionUseCaseFactory.swift +// FLINT +// +// Created by 소은 on 6/21/26. +// + +import Foundation + +import Domain + +protocol ReportCollectionUseCaseFactory: CollectionRepositoryFactory { + func makeReportCollectionUseCase() -> ReportCollectionUseCase +} + +extension ReportCollectionUseCaseFactory { + func makeReportCollectionUseCase() -> ReportCollectionUseCase { + return DefaultReportCollectionUseCase(collectionRepository: makeCollectionRepository()) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/ViewController/ReportViewControllerFactory+.swift b/FLINT/FLINT/Dependency/Factory/ViewController/ReportViewControllerFactory+.swift new file mode 100644 index 00000000..39378e6a --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/ViewController/ReportViewControllerFactory+.swift @@ -0,0 +1,17 @@ +// +// ReportViewControllerFactory+.swift +// FLINT +// + +import Foundation + +import Presentation + +extension ReportViewControllerFactory where Self: ReportViewModelFactory & ViewControllerFactory { + func makeReportViewController(collectionId: Int64) -> ReportViewController { + return ReportViewController( + viewModel: makeReportViewModel(collectionId: collectionId), + viewControllerFactory: self + ) + } +} diff --git a/FLINT/FLINT/Dependency/Factory/ViewModel/ReportViewModelFactory.swift b/FLINT/FLINT/Dependency/Factory/ViewModel/ReportViewModelFactory.swift new file mode 100644 index 00000000..ca5406a1 --- /dev/null +++ b/FLINT/FLINT/Dependency/Factory/ViewModel/ReportViewModelFactory.swift @@ -0,0 +1,20 @@ +// +// ReportViewModelFactory.swift +// FLINT +// +// Created by 소은 on 6/21/26. +// + +import Foundation + +import Presentation + +protocol ReportViewModelFactory: ReportCollectionUseCaseFactory { + func makeReportViewModel(collectionId: Int64) -> ReportViewModel +} + +extension ReportViewModelFactory { + func makeReportViewModel(collectionId: Int64) -> ReportViewModel { + return ReportViewModel(reportCollectionUseCase: makeReportCollectionUseCase(), collectionId: collectionId) + } +} diff --git a/FLINT/Presentation/Sources/ViewController/Dependency/ViewControllerFactory.swift b/FLINT/Presentation/Sources/ViewController/Dependency/ViewControllerFactory.swift index 2ed18798..098135ec 100644 --- a/FLINT/Presentation/Sources/ViewController/Dependency/ViewControllerFactory.swift +++ b/FLINT/Presentation/Sources/ViewController/Dependency/ViewControllerFactory.swift @@ -18,11 +18,11 @@ public typealias ViewControllerFactory = // MARK: - Onboarding - TermsAgreementViewControllerFactory & NicknameViewControllerFactory & ContentSelectViewControllerFactory & // OttSelectViewControllerFactory & OnboardingDoneViewControllerFactory & + TermsAgreementViewControllerFactory & // MARK: - Main @@ -36,4 +36,5 @@ public typealias ViewControllerFactory = CollectionFolderListViewControllerFactory & CollectionDetailViewControllerFactory & AddContentSelectViewControllerFactory & - CreateCollectionViewControllerFactory + CreateCollectionViewControllerFactory & + ReportViewControllerFactory diff --git a/FLINT/Presentation/Sources/ViewController/ReportViewController.swift b/FLINT/Presentation/Sources/ViewController/ReportViewController.swift index 0ee0235e..223cfa70 100644 --- a/FLINT/Presentation/Sources/ViewController/ReportViewController.swift +++ b/FLINT/Presentation/Sources/ViewController/ReportViewController.swift @@ -11,6 +11,14 @@ import Combine import View import ViewModel +// MARK: - ReportViewControllerFactory + +public protocol ReportViewControllerFactory { + func makeReportViewController(collectionId: Int64) -> ReportViewController +} + +// MARK: - ReportViewController + public final class ReportViewController: BaseViewController { // MARK: - Property @@ -29,10 +37,9 @@ public final class ReportViewController: BaseViewController { // MARK: - Init - public init(viewModel: ReportViewModel) { + public init(viewModel: ReportViewModel, viewControllerFactory: (any ViewControllerFactory)?) { self.viewModel = viewModel - // FIXME: viewControllerFactor 주입 - super.init(viewControllerFactory: nil) + super.init(viewControllerFactory: viewControllerFactory) } required init?(coder: NSCoder) { @@ -98,13 +105,13 @@ public final class ReportViewController: BaseViewController { } private func setupTextViewObserver() { - NotificationCenter.default.addObserver( - self, - selector: #selector(textViewDidBeginEditing), - name: UITextView.textDidBeginEditingNotification, - object: rootView.textView - ) - } + NotificationCenter.default.addObserver( + self, + selector: #selector(textViewDidBeginEditing), + name: UITextView.textDidBeginEditingNotification, + object: rootView.textView + ) + } private func setupActions() { for (index, button) in rootView.radioButtons.enumerated() { @@ -150,7 +157,6 @@ public final class ReportViewController: BaseViewController { selectedRadioIndex = 4 radioSelectionSubject.send(4) } - // MARK: - Custom Method diff --git a/FLINT/Presentation/Sources/ViewController/Scene/Onboarding/TermsAgreement/TermsAgreementViewController.swift b/FLINT/Presentation/Sources/ViewController/Scene/Onboarding/TermsAgreement/TermsAgreementViewController.swift index 15f959b1..e4c5af1e 100644 --- a/FLINT/Presentation/Sources/ViewController/Scene/Onboarding/TermsAgreement/TermsAgreementViewController.swift +++ b/FLINT/Presentation/Sources/ViewController/Scene/Onboarding/TermsAgreement/TermsAgreementViewController.swift @@ -28,10 +28,10 @@ public final class TermsAgreementViewController: BaseViewController() - private var selectedRadioIndex: Int? + + private static let reasonKeys = ["ABUSE", "OBSCENE", "SPAM", "COPYRIGHT", "OTHER"] + + private var selectedRadioIndex: Int = -1 private var textInput: String = "" // MARK: - Init - public init() {} + public init(reportCollectionUseCase: ReportCollectionUseCase, collectionId: Int64) { + self.reportCollectionUseCase = reportCollectionUseCase + self.collectionId = collectionId + } // MARK: - Input @@ -50,15 +60,11 @@ public final class ReportViewModel { public func transform(input: Input) -> Output { input.radioSelected - .sink { [weak self] index in - self?.selectedRadioIndex = index - } + .sink { [weak self] index in self?.selectedRadioIndex = index } .store(in: &cancellables) input.textInput - .sink { [weak self] text in - self?.textInput = text - } + .sink { [weak self] text in self?.textInput = text } .store(in: &cancellables) let isSubmitEnabledPublisher = Publishers.CombineLatest( @@ -66,39 +72,36 @@ public final class ReportViewModel { input.textInput.prepend("") ) .map { radioIndex, text -> Bool in - if radioIndex == -1 { - return false - } - if radioIndex == 4 { - return !text.isEmpty - } + if radioIndex == -1 { return false } + if radioIndex == 4 { return !text.isEmpty } return true } .eraseToAnyPublisher() let submitResult = input.submitButtonTapped .flatMap { [weak self] _ -> AnyPublisher, Never> in - guard let self = self else { + guard let self, self.selectedRadioIndex >= 0 else { return Empty().eraseToAnyPublisher() } - return self.submitReport() + let reason = Self.reasonKeys[self.selectedRadioIndex] + let otherDetail = self.selectedRadioIndex == 4 ? self.textInput : nil + return self.reportCollectionUseCase(collectionId: self.collectionId, reasons: [reason], otherDetail: otherDetail) + .map { Result.success($0) } + .catch { Just(Result.failure($0)) } + .eraseToAnyPublisher() } .share() let submitSuccess = submitResult .compactMap { result -> Void? in - if case .success = result { - return () - } + if case .success = result { return () } return nil } .eraseToAnyPublisher() let submitError = submitResult .compactMap { result -> Error? in - if case .failure(let error) = result { - return error - } + if case .failure(let error) = result { return error } return nil } .eraseToAnyPublisher() @@ -109,14 +112,4 @@ public final class ReportViewModel { submitError: submitError ) } - - // MARK: - Custom Method - - private func submitReport() -> AnyPublisher, Never> { - // TODO: UseCase 호출 - - // 임시 구현 - return Just(Result.success(())) - .eraseToAnyPublisher() - } } From d40e83a7d857f8d051b3e3d88d0ec50e31f7d547 Mon Sep 17 00:00:00 2001 From: soonny <134983918+soeun11@users.noreply.github.com> Date: Sat, 27 Jun 2026 22:07:51 +0900 Subject: [PATCH 4/6] =?UTF-8?q?[feat]=20=EC=84=B8=ED=8C=85=20=EB=B7=B0=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FLINT/FLINT/Dependency/DIContainer.swift | 6 +----- .../ViewController/Scene/Home/HomeViewController.swift | 2 +- .../Scene/Profile/ProfileViewController.swift | 5 +++-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/FLINT/FLINT/Dependency/DIContainer.swift b/FLINT/FLINT/Dependency/DIContainer.swift index 57c9e6cb..23ecd96c 100644 --- a/FLINT/FLINT/Dependency/DIContainer.swift +++ b/FLINT/FLINT/Dependency/DIContainer.swift @@ -24,13 +24,9 @@ typealias DependencyFactory = ViewControllerFactory & FetchOTTPlatformsForContentUseCaseFactory & ExploreViewModelFactory & ProfileViewModelFactory & - -<<<<<<< HEAD - ReportViewModelFactory & -======= + SettingViewModelFactory & WithdrawViewModelFactory & ->>>>>>> network/#201-setting-api CreateCollectionViewModelFactory & AddContentSelectViewModelFactory & diff --git a/FLINT/Presentation/Sources/ViewController/Scene/Home/HomeViewController.swift b/FLINT/Presentation/Sources/ViewController/Scene/Home/HomeViewController.swift index ce15e83e..01ab5b8b 100644 --- a/FLINT/Presentation/Sources/ViewController/Scene/Home/HomeViewController.swift +++ b/FLINT/Presentation/Sources/ViewController/Scene/Home/HomeViewController.swift @@ -32,7 +32,7 @@ public final class HomeViewController: BaseViewController { ) { self.viewModel = viewModel self.fetchOTTPlatformsForContentUseCase = fetchOTTPlatformsForContentUseCase - super.init(nibName: nil, bundle: nil) + super.init(viewControllerFactory: viewControllerFactory) self.viewControllerFactory = viewControllerFactory } diff --git a/FLINT/Presentation/Sources/ViewController/Scene/Profile/ProfileViewController.swift b/FLINT/Presentation/Sources/ViewController/Scene/Profile/ProfileViewController.swift index 09ef485a..ae04cfe9 100644 --- a/FLINT/Presentation/Sources/ViewController/Scene/Profile/ProfileViewController.swift +++ b/FLINT/Presentation/Sources/ViewController/Scene/Profile/ProfileViewController.swift @@ -62,8 +62,9 @@ public final class ProfileViewController: BaseViewController { } private func didTapSetting() { - // TODO: SettingViewController push (DI에 SettingViewControllerFactory 등록 후 연결) - print("setting tapped") + guard let factory = viewControllerFactory else { return } + let settingVC = factory.makeSettingViewController() + navigationController?.pushViewController(settingVC, animated: true) } private func setupTableView() { From 2fb0fd2be436b9cd8bd03586e7695b8e7adfca5c Mon Sep 17 00:00:00 2001 From: soonny <134983918+soeun11@users.noreply.github.com> Date: Sat, 27 Jun 2026 22:12:35 +0900 Subject: [PATCH 5/6] =?UTF-8?q?[feat]=20=EB=A1=9C=EA=B7=B8=EC=95=84?= =?UTF-8?q?=EC=9B=83=20=EA=B8=B0=EB=8A=A5=20=ED=99=95=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/Networking/Service/AuthService.swift | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/FLINT/Data/Sources/Networking/Service/AuthService.swift b/FLINT/Data/Sources/Networking/Service/AuthService.swift index 8f36f3a7..ce41afe2 100644 --- a/FLINT/Data/Sources/Networking/Service/AuthService.swift +++ b/FLINT/Data/Sources/Networking/Service/AuthService.swift @@ -74,18 +74,18 @@ public final class DefaultAuthService: AuthService { } return authAPIProvider.requestPublisher(.logout(refreshToken: refreshToken)) .logged() - .mapBaseResponseData(BlankData.self) - .map({ [weak self] _ in + .tryMap { [weak self] response in + guard (200..<300).contains(response.statusCode) else { + throw MoyaError.statusCode(response) + } self?.tokenStorage.clearAll() - }) + } .eraseToAnyPublisher() } public func withDraw(agreedTermsIds: [String]) -> AnyPublisher { return authAPIProvider.requestPublisher(.withdraw(agreedTermsIds: agreedTermsIds)) .logged() - .mapBaseResponseData(BlankData.self) - .map({ _ in }) - .eraseToAnyPublisher() + .mapBaseResponseEmpty() } } From 20dde1b51d3b6f93fc5c99be7130e83f47f4bb41 Mon Sep 17 00:00:00 2001 From: soonny <134983918+soeun11@users.noreply.github.com> Date: Sat, 27 Jun 2026 22:40:00 +0900 Subject: [PATCH 6/6] =?UTF-8?q?[fix]=20ott=20list=20=EC=95=88=EB=9C=A8?= =?UTF-8?q?=EB=8A=94=EB=AC=B8=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ViewController/Scene/Home/HomeViewController.swift | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/FLINT/Presentation/Sources/ViewController/Scene/Home/HomeViewController.swift b/FLINT/Presentation/Sources/ViewController/Scene/Home/HomeViewController.swift index 01ab5b8b..915d7bb9 100644 --- a/FLINT/Presentation/Sources/ViewController/Scene/Home/HomeViewController.swift +++ b/FLINT/Presentation/Sources/ViewController/Scene/Home/HomeViewController.swift @@ -109,7 +109,7 @@ public final class HomeViewController: BaseViewController { title: "이 작품을 볼 수 있는 OTT", content: .ott(platforms: platforms) ) - present(vc, animated: false) + present(vc, animated: true) } private func fetchAndPresentOTT(contentId: Int64) { @@ -246,9 +246,10 @@ extension HomeViewController: UITableViewDataSource { cell.onTapItem = { [weak self] content in guard let self else { return } - guard let contentId = Int64(content.id) else { return } - - self.fetchAndPresentOTT(contentId: contentId) + let platforms: [OTTPlatform] = content.ottList.compactMap { ott in + OTTPlatform.fromServerName(ott.ottName) + } + self.presentOTTBottomSheet(platforms: platforms) } return cell