From de3bd9424fca5c04fec75a10a8a92e65e26a47cb Mon Sep 17 00:00:00 2001 From: 051198Hz Date: Mon, 2 Dec 2024 11:55:26 +0900 Subject: [PATCH 1/9] =?UTF-8?q?[REFACTOR]:=20=EC=97=AC=EB=9F=AC=20?= =?UTF-8?q?=EC=9C=A0=EC=A6=88=EC=BC=80=EC=9D=B4=EC=8A=A4=EB=A5=BC=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=A8=EC=9C=BC=EB=A1=9C=20=EC=9D=B8?= =?UTF-8?q?=ED=95=9C=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...enSharedContainerRepositoryInterface.swift | 8 ++++++ .../OpenSharedContainerUseCaseInterface.swift | 12 +++++++++ .../UseCase/OpenSharedContainerUseCase.swift | 8 ++++++ .../ViewModel/ConnectionViewModel.swift | 27 ++++++++++--------- 4 files changed, 43 insertions(+), 12 deletions(-) create mode 100644 Domain/Interfaces/RepositoryInterface/OpenSharedContainerRepositoryInterface.swift create mode 100644 Domain/Interfaces/UseCaseInterface/OpenSharedContainerUseCaseInterface.swift create mode 100644 Domain/UseCase/OpenSharedContainerUseCase.swift diff --git a/Domain/Interfaces/RepositoryInterface/OpenSharedContainerRepositoryInterface.swift b/Domain/Interfaces/RepositoryInterface/OpenSharedContainerRepositoryInterface.swift new file mode 100644 index 00000000..b3fbb3f4 --- /dev/null +++ b/Domain/Interfaces/RepositoryInterface/OpenSharedContainerRepositoryInterface.swift @@ -0,0 +1,8 @@ +// +// OpenSharedContainerRepositoryInterface.swift +// Interfaces +// +// Created by Yune gim on 12/2/24. +// + +import Foundation diff --git a/Domain/Interfaces/UseCaseInterface/OpenSharedContainerUseCaseInterface.swift b/Domain/Interfaces/UseCaseInterface/OpenSharedContainerUseCaseInterface.swift new file mode 100644 index 00000000..5118f31f --- /dev/null +++ b/Domain/Interfaces/UseCaseInterface/OpenSharedContainerUseCaseInterface.swift @@ -0,0 +1,12 @@ +// +// OpenSharedContainerUseCaseInterface.swift +// Interfaces +// +// Created by Yune gim on 12/2/24. +// + +import Combine + +public protocol OpenSharedContainerUseCaseInterface { + +} diff --git a/Domain/UseCase/OpenSharedContainerUseCase.swift b/Domain/UseCase/OpenSharedContainerUseCase.swift new file mode 100644 index 00000000..455e6a72 --- /dev/null +++ b/Domain/UseCase/OpenSharedContainerUseCase.swift @@ -0,0 +1,8 @@ +// +// OpenSharedContainerUseCase.swift +// UseCase +// +// Created by Yune gim on 12/2/24. +// + +import Foundation diff --git a/Feature/Feature/ConnectionView/ViewModel/ConnectionViewModel.swift b/Feature/Feature/ConnectionView/ViewModel/ConnectionViewModel.swift index 7cf109c1..b32fffd6 100644 --- a/Feature/Feature/ConnectionView/ViewModel/ConnectionViewModel.swift +++ b/Feature/Feature/ConnectionView/ViewModel/ConnectionViewModel.swift @@ -18,7 +18,7 @@ final public class ConnectionViewModel { // MARK: - Properties - private let usecase: BrowsingUserUseCaseInterface + private let browsingUserUseCase: BrowsingUserUseCaseInterface private var output = PassthroughSubject() private var cancellables: Set = [] @@ -29,8 +29,9 @@ final public class ConnectionViewModel { // MARK: - Initializer - public init(usecase: BrowsingUserUseCaseInterface) { - self.usecase = usecase + public init(browsingUserUseCase: BrowsingUserUseCaseInterface, + openSharedContainerUseCase: OpenSharedContainerUseCaseInterface) { + self.browsingUserUseCase = browsingUserUseCase setupBind() } @@ -61,17 +62,19 @@ extension ConnectionViewModel { // Connection Input case .fetchUsers: - usecase.fetchBrowsedUsers().forEach({ self.found(user: $0) }) + browsingUserUseCase.fetchBrowsedUsers().forEach({ self.found(user: $0) }) case .inviteUser(let id): - usecase.inviteUser(with: id) + browsingUserUseCase.inviteUser(with: id) // Invitation Input case .acceptInvitation(let user): - usecase.acceptInvitation() + browsingUserUseCase.acceptInvitation() removeCurrentPosition(id: user.id) case .rejectInvitation: - usecase.rejectInvitation() + browsingUserUseCase.rejectInvitation() + case .nextButtonDidTapped: + output.send(.openSharedVideoList) } } .store(in: &cancellables) @@ -86,7 +89,7 @@ private extension ConnectionViewModel { func setupBind() { // Broswed User (found, lost) - usecase.browsedUser + browsingUserUseCase.browsedUser .sink { [weak self] updatedUser in guard let self else { return } @@ -101,7 +104,7 @@ private extension ConnectionViewModel { // Invitation Received (From Who) - usecase.invitationReceived + browsingUserUseCase.invitationReceived .sink { [weak self] invitingUser in guard let self else { return } output.send(.invitationReceivedBy(user: invitingUser)) @@ -110,7 +113,7 @@ private extension ConnectionViewModel { // Invitation Result (when I invite other users) - usecase.invitationResult + browsingUserUseCase.invitationResult .sink { [weak self] invitedUser in guard let self else { return } @@ -130,12 +133,12 @@ private extension ConnectionViewModel { // Invitaion Fired Due to Timeout (invited user receive) - usecase.invitationDidFired + browsingUserUseCase.invitationDidFired .sink { [weak self] in guard let self else { return } output.send(.invitationTimeout) - usecase.rejectInvitation() + browsingUserUseCase.rejectInvitation() } .store(in: &cancellables) } From 67e2179bfe011c026fd2a071ef8fa437a4299879 Mon Sep 17 00:00:00 2001 From: 051198Hz Date: Mon, 2 Dec 2024 15:58:29 +0900 Subject: [PATCH 2/9] =?UTF-8?q?[FEAT]:=20=ED=94=BC=EC=96=B4=EC=97=90?= =?UTF-8?q?=EA=B2=8C=EC=84=9C=20=EC=A0=84=EC=86=A1=ED=95=A0=20=EC=9D=B4?= =?UTF-8?q?=EB=B2=A4=ED=8A=B8=EC=99=80=20=EC=A0=84=EB=8B=AC=EB=B0=9B?= =?UTF-8?q?=EC=9D=80=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=EB=A5=BC=20=EB=B0=A9?= =?UTF-8?q?=EC=B6=9C=ED=95=A0=20NoticedEventRepository=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=86=A0=EC=BD=9C=20=EB=B0=8F=20=EA=B5=AC=ED=98=84?= =?UTF-8?q?=EC=B2=B4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Data/Data/EventRepository.swift | 39 +++++++++++++++++++ Domain/Entity/Event.swift | 10 +++++ .../EventRepositoryInterface.swift | 15 +++++++ 3 files changed, 64 insertions(+) create mode 100644 Data/Data/EventRepository.swift create mode 100644 Domain/Entity/Event.swift create mode 100644 Domain/Interfaces/RepositoryInterface/EventRepositoryInterface.swift diff --git a/Data/Data/EventRepository.swift b/Data/Data/EventRepository.swift new file mode 100644 index 00000000..b3b9c884 --- /dev/null +++ b/Data/Data/EventRepository.swift @@ -0,0 +1,39 @@ +// +// NoticedEventRepository.swift +// Data +// +// Created by Yune gim on 12/2/24. +// + +import Combine +import Entity +import Foundation +import Interfaces +import P2PSocket + +public final class NoticedEventRepository: NoticedEventRepositoryInterface { + private var cancellables: Set = [] + private let socketProvider: SocketProvidable + + public var receivedEvent = PassthroughSubject() + + public init(socketProvider: SocketProvidable) { + self.socketProvider = socketProvider + bind() + } + + public func notice(event: Event) { + guard let eventData = try? JSONEncoder().encode(event) else { return } + socketProvider.sendAll(data: eventData) + } +} + +private extension NoticedEventRepository { + func bind() { + socketProvider.dataShared.sink { [weak self] (data, _) in + guard let event = try? JSONDecoder().decode(Event.self, from: data) else { return } + self?.receivedEvent.send(event) + } + .store(in: &cancellables) + } +} diff --git a/Domain/Entity/Event.swift b/Domain/Entity/Event.swift new file mode 100644 index 00000000..27d2b4c3 --- /dev/null +++ b/Domain/Entity/Event.swift @@ -0,0 +1,10 @@ +// +// Event.swift +// Entity +// +// Created by Yune gim on 12/2/24. +// + +public enum Event: Codable { + case openSharedContainer +} diff --git a/Domain/Interfaces/RepositoryInterface/EventRepositoryInterface.swift b/Domain/Interfaces/RepositoryInterface/EventRepositoryInterface.swift new file mode 100644 index 00000000..d62750e0 --- /dev/null +++ b/Domain/Interfaces/RepositoryInterface/EventRepositoryInterface.swift @@ -0,0 +1,15 @@ +// +// NoticedEventRepositoryInterface.swift +// Interfaces +// +// Created by Yune gim on 12/2/24. +// + +import Combine +import Entity + +public protocol NoticedEventRepositoryInterface { + var receivedEvent: PassthroughSubject { get } + + func notice(event: Event) +} From d19b0fcbf0e7b1294be3352932061e700333256e Mon Sep 17 00:00:00 2001 From: 051198Hz Date: Mon, 2 Dec 2024 15:59:57 +0900 Subject: [PATCH 3/9] =?UTF-8?q?[FEAT]:=20=ED=94=BC=EC=96=B4=EB=93=A4?= =?UTF-8?q?=EC=97=90=EA=B2=8C=20=EA=B3=B5=EC=9C=A0=20=EC=BB=A8=ED=85=8C?= =?UTF-8?q?=EC=9D=B4=EB=84=88=EB=A5=BC=20=EC=97=B4=EB=9D=BC=EB=8A=94=20?= =?UTF-8?q?=EC=9D=B4=EB=B2=A4=ED=8A=B8=EB=A5=BC=20=EC=95=8C=EB=A6=AC?= =?UTF-8?q?=EA=B3=A0,=20=EC=A0=84=EB=8B=AC=EB=B0=9B=EB=8A=94=20OpenSharedC?= =?UTF-8?q?ontainerUseCase=20=ED=94=84=EB=A1=9C=ED=86=A0=EC=BD=9C=20?= =?UTF-8?q?=EB=B0=8F=20=EA=B5=AC=ED=98=84=EC=B2=B4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OpenSharedContainerUseCaseInterface.swift | 2 + .../UseCase/OpenSharedContainerUseCase.swift | 37 ++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/Domain/Interfaces/UseCaseInterface/OpenSharedContainerUseCaseInterface.swift b/Domain/Interfaces/UseCaseInterface/OpenSharedContainerUseCaseInterface.swift index 5118f31f..e65284a8 100644 --- a/Domain/Interfaces/UseCaseInterface/OpenSharedContainerUseCaseInterface.swift +++ b/Domain/Interfaces/UseCaseInterface/OpenSharedContainerUseCaseInterface.swift @@ -8,5 +8,7 @@ import Combine public protocol OpenSharedContainerUseCaseInterface { + var openEvent: PassthroughSubject { get } + func noticeOpening() } diff --git a/Domain/UseCase/OpenSharedContainerUseCase.swift b/Domain/UseCase/OpenSharedContainerUseCase.swift index 455e6a72..e5fe2335 100644 --- a/Domain/UseCase/OpenSharedContainerUseCase.swift +++ b/Domain/UseCase/OpenSharedContainerUseCase.swift @@ -5,4 +5,39 @@ // Created by Yune gim on 12/2/24. // -import Foundation +import Combine +import Entity +import Interfaces + +public final class OpenSharedContainerUseCase: OpenSharedContainerUseCaseInterface { + private let repository: NoticedEventRepositoryInterface + private var cancellables: Set = [] + + public var openEvent = PassthroughSubject() + + public init(repository: NoticedEventRepositoryInterface) { + self.repository = repository + bind() + } +} + +// MARK: - Public Methods +public extension OpenSharedContainerUseCase { + func noticeOpening() { + repository.notice(event: Event.openSharedContainer) + openEvent.send() + } +} + +// MARK: - Private Methods +private extension OpenSharedContainerUseCase { + func bind() { + repository.receivedEvent + .sink { [weak self] event in + if event == .openSharedContainer { + self?.openEvent.send() + } + } + .store(in: &cancellables) + } +} From bd45d0b6d76b2f48cbe648b96e0dd8c0415d684c Mon Sep 17 00:00:00 2001 From: 051198Hz Date: Mon, 2 Dec 2024 16:00:39 +0900 Subject: [PATCH 4/9] =?UTF-8?q?[FEAT]:=20=EB=B2=84=ED=8A=BC=EC=9D=B4=20?= =?UTF-8?q?=ED=83=AD=20=EB=90=9C=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20=EC=9E=85=EB=A0=A5,=20=EA=B3=B5=EC=9C=A0?= =?UTF-8?q?=20=EC=BB=A8=ED=85=8C=EC=9D=B4=EB=84=88=EB=A5=BC=20=EC=97=AC?= =?UTF-8?q?=EB=8A=94=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=EC=97=90=20=EB=8C=80?= =?UTF-8?q?=ED=95=9C=20=EC=B6=9C=EB=A0=A5=EC=9D=84=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ConnectionView/ViewModel/ConnectionViewInputOutput.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Feature/Feature/ConnectionView/ViewModel/ConnectionViewInputOutput.swift b/Feature/Feature/ConnectionView/ViewModel/ConnectionViewInputOutput.swift index 13dfb0d9..531460da 100644 --- a/Feature/Feature/ConnectionView/ViewModel/ConnectionViewInputOutput.swift +++ b/Feature/Feature/ConnectionView/ViewModel/ConnectionViewInputOutput.swift @@ -20,6 +20,7 @@ enum ConnectionViewInput { case acceptInvitation(user: BrowsedUser) case rejectInvitation + case nextButtonDidTapped } // MARK: - Output @@ -36,4 +37,5 @@ enum ConnectionViewOutput { case invitationAcceptedBy(user: BrowsedUser) case invitationRejectedBy(name: String) case invitationTimeout + case openSharedVideoList } From 81100e1fde2b4a30e50111e098200118c9d99838 Mon Sep 17 00:00:00 2001 From: 051198Hz Date: Mon, 2 Dec 2024 16:01:25 +0900 Subject: [PATCH 5/9] =?UTF-8?q?[FEAT]:=20=ED=8E=B8=EC=A7=91=ED=95=98?= =?UTF-8?q?=EA=B8=B0=20=EB=B2=84=ED=8A=BC=EC=9D=84=20=EB=88=8C=EB=9F=AC=20?= =?UTF-8?q?=EB=AA=A8=EB=93=A0=20=ED=94=BC=EC=96=B4=EA=B0=80=20=EA=B3=B5?= =?UTF-8?q?=EC=9C=A0=20=EC=BB=A8=ED=85=8C=EC=9D=B4=EB=84=88=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=EC=9C=BC=EB=A1=9C=20=EC=A7=84=ED=99=98=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EA=B8=B0=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 --- .../ConnectionView/ConnectionViewController.swift | 15 +++++++++++---- .../ViewModel/ConnectionViewModel.swift | 11 ++++++++++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Feature/Feature/ConnectionView/ConnectionViewController.swift b/Feature/Feature/ConnectionView/ConnectionViewController.swift index 714c6bc4..164266d2 100644 --- a/Feature/Feature/ConnectionView/ConnectionViewController.swift +++ b/Feature/Feature/ConnectionView/ConnectionViewController.swift @@ -124,6 +124,8 @@ extension ConnectionViewController { present(UIAlertController( type: .invitationTimeout, actions: [.confirm(), .cancel()]), animated: true) + case .openSharedVideoList: + openVideoList() } } .store(in: &cancellables) @@ -152,10 +154,7 @@ private extension ConnectionViewController { } func nextButtonDidTapped() { - let videoListViewController = VideoListViewController( - viewModel: DIContainer.shared.resolve(type: MultipeerVideoListViewModel.self) - ) - self.navigationController?.pushViewController(videoListViewController, animated: true) + input.send(.nextButtonDidTapped) } } @@ -206,6 +205,14 @@ private extension ConnectionViewController { func resetCurrentUserId() { currentUserId = nil } + + func openVideoList() { + let videoListViewController = VideoListViewController( + viewModel: DIContainer.shared.resolve(type: MultipeerVideoListViewModel.self) + ) + guard navigationController?.viewControllers.last === self else { return } + self.navigationController?.pushViewController(videoListViewController, animated: true) + } } // MARK: - UI Configure diff --git a/Feature/Feature/ConnectionView/ViewModel/ConnectionViewModel.swift b/Feature/Feature/ConnectionView/ViewModel/ConnectionViewModel.swift index b32fffd6..b99f25df 100644 --- a/Feature/Feature/ConnectionView/ViewModel/ConnectionViewModel.swift +++ b/Feature/Feature/ConnectionView/ViewModel/ConnectionViewModel.swift @@ -19,6 +19,7 @@ final public class ConnectionViewModel { // MARK: - Properties private let browsingUserUseCase: BrowsingUserUseCaseInterface + private let openSharedContainerUseCase: OpenSharedContainerUseCaseInterface private var output = PassthroughSubject() private var cancellables: Set = [] @@ -32,6 +33,7 @@ final public class ConnectionViewModel { public init(browsingUserUseCase: BrowsingUserUseCaseInterface, openSharedContainerUseCase: OpenSharedContainerUseCaseInterface) { self.browsingUserUseCase = browsingUserUseCase + self.openSharedContainerUseCase = openSharedContainerUseCase setupBind() } @@ -74,7 +76,7 @@ extension ConnectionViewModel { case .rejectInvitation: browsingUserUseCase.rejectInvitation() case .nextButtonDidTapped: - output.send(.openSharedVideoList) + openSharedContainerUseCase.noticeOpening() } } .store(in: &cancellables) @@ -141,6 +143,13 @@ private extension ConnectionViewModel { browsingUserUseCase.rejectInvitation() } .store(in: &cancellables) + + openSharedContainerUseCase.openEvent + .sink { [weak self] in + guard let self else { return } + output.send(.openSharedVideoList) + } + .store(in: &cancellables) } } From c87cac211fe5bc704fe525407f0c9e5f04118193 Mon Sep 17 00:00:00 2001 From: 051198Hz Date: Mon, 2 Dec 2024 16:01:43 +0900 Subject: [PATCH 6/9] =?UTF-8?q?[FEAT]:=20DI=EC=BB=A8=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=84=88=EC=97=90=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App/App/SceneDelegate.swift | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/App/App/SceneDelegate.swift b/App/App/SceneDelegate.swift index e02bed31..8f45304f 100644 --- a/App/App/SceneDelegate.swift +++ b/App/App/SceneDelegate.swift @@ -71,6 +71,12 @@ extension SceneDelegate { socketProvider: DIContainer.shared.resolve(type: SocketProvidable.self) ) ) + DIContainer.shared.register( + type: NoticedEventRepositoryInterface.self, + instance: NoticedEventRepository( + socketProvider: DIContainer.shared.resolve(type: SocketProvidable.self) + ) + ) } func registerUseCase() { @@ -92,13 +98,23 @@ extension SceneDelegate { type: VideoUseCaseInterface.self, instance: VideoUseCase( repository: DIContainer.shared.resolve(type: SharingVideoRepositoryInterface.self))) + + DIContainer.shared.register( + type: OpenSharedContainerUseCaseInterface.self, + instance: OpenSharedContainerUseCase( + repository: DIContainer.shared.resolve(type: NoticedEventRepositoryInterface.self))) } func registerViewModel() { DIContainer.shared.register( type: ConnectionViewModel.self, instance: ConnectionViewModel( - usecase: DIContainer.shared.resolve(type: BrowsingUserUseCaseInterface.self) + browsingUserUseCase: DIContainer.shared.resolve( + type: BrowsingUserUseCaseInterface.self + ), + openSharedContainerUseCase: DIContainer.shared.resolve( + type: OpenSharedContainerUseCaseInterface.self + ) ) ) From 31d8d7e73bdbe07428384e35d2b53240b129fb1b Mon Sep 17 00:00:00 2001 From: 051198Hz Date: Mon, 2 Dec 2024 16:02:23 +0900 Subject: [PATCH 7/9] =?UTF-8?q?[CHORE]:=20=ED=8C=8C=EC=9D=BC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=EC=A0=9D=ED=8A=B8=20=EB=B3=80=EA=B2=BD=EC=82=AC=ED=95=AD=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Data/Data.xcodeproj/project.pbxproj | 1 + Domain/Domain.xcodeproj/project.pbxproj | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Data/Data.xcodeproj/project.pbxproj b/Data/Data.xcodeproj/project.pbxproj index 0dcfdc8c..cc3d25ec 100644 --- a/Data/Data.xcodeproj/project.pbxproj +++ b/Data/Data.xcodeproj/project.pbxproj @@ -66,6 +66,7 @@ membershipExceptions = ( BrowsingUserRepository.swift, ConnectedUserRepository.swift, + EventRepository.swift, SharingVideoRepository.swift, ); target = FED968292CD9094300CD445C /* Data */; diff --git a/Domain/Domain.xcodeproj/project.pbxproj b/Domain/Domain.xcodeproj/project.pbxproj index 5da35bb4..1c204c55 100644 --- a/Domain/Domain.xcodeproj/project.pbxproj +++ b/Domain/Domain.xcodeproj/project.pbxproj @@ -122,8 +122,8 @@ membershipExceptions = ( BrowsingUserUseCase.swift, ConnectedUserUseCase.swift, + OpenSharedContainerUseCase.swift, VideoUseCase.swift, - ); target = FE6EF3C62CD8B5CA005DC39D /* UseCase */; }; From 13d99ab28d2fb2bdf51711a0b428db2c33858a99 Mon Sep 17 00:00:00 2001 From: 051198Hz Date: Mon, 2 Dec 2024 20:53:53 +0900 Subject: [PATCH 8/9] =?UTF-8?q?[REFACTOR]:=20BrowsingUserRepository?= =?UTF-8?q?=EB=A1=9C=20=EA=B3=B5=EC=9C=A0=EC=BB=A8=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=84=88=20=ED=99=94=EB=A9=B4=20=EC=A0=84=ED=99=98=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=ED=86=B5=ED=95=A9=20=EB=B0=8F=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=EC=82=AC=ED=95=AD=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App/App/SceneDelegate.swift | 18 +------- Data/Data.xcodeproj/project.pbxproj | 1 - Data/Data/BrowsingUserRepository.swift | 15 +++++++ Domain/Domain.xcodeproj/project.pbxproj | 1 - .../{Event.swift => OpeningEvent.swift} | 4 +- .../BrowsingUserRepositoryInterface.swift | 4 +- .../EventRepositoryInterface.swift | 15 ------- ...enSharedContainerRepositoryInterface.swift | 8 ---- .../BrowsingUserUseCaseInterface.swift | 3 ++ .../OpenSharedContainerUseCaseInterface.swift | 14 ------ Domain/UseCase/BrowsingUserUseCase.swift | 12 ++++++ .../UseCase/OpenSharedContainerUseCase.swift | 43 ------------------- .../ViewModel/ConnectionViewModel.swift | 31 ++++++------- 13 files changed, 50 insertions(+), 119 deletions(-) rename Domain/Entity/{Event.swift => OpeningEvent.swift} (55%) delete mode 100644 Domain/Interfaces/RepositoryInterface/EventRepositoryInterface.swift delete mode 100644 Domain/Interfaces/RepositoryInterface/OpenSharedContainerRepositoryInterface.swift delete mode 100644 Domain/Interfaces/UseCaseInterface/OpenSharedContainerUseCaseInterface.swift delete mode 100644 Domain/UseCase/OpenSharedContainerUseCase.swift diff --git a/App/App/SceneDelegate.swift b/App/App/SceneDelegate.swift index 8f45304f..e02bed31 100644 --- a/App/App/SceneDelegate.swift +++ b/App/App/SceneDelegate.swift @@ -71,12 +71,6 @@ extension SceneDelegate { socketProvider: DIContainer.shared.resolve(type: SocketProvidable.self) ) ) - DIContainer.shared.register( - type: NoticedEventRepositoryInterface.self, - instance: NoticedEventRepository( - socketProvider: DIContainer.shared.resolve(type: SocketProvidable.self) - ) - ) } func registerUseCase() { @@ -98,23 +92,13 @@ extension SceneDelegate { type: VideoUseCaseInterface.self, instance: VideoUseCase( repository: DIContainer.shared.resolve(type: SharingVideoRepositoryInterface.self))) - - DIContainer.shared.register( - type: OpenSharedContainerUseCaseInterface.self, - instance: OpenSharedContainerUseCase( - repository: DIContainer.shared.resolve(type: NoticedEventRepositoryInterface.self))) } func registerViewModel() { DIContainer.shared.register( type: ConnectionViewModel.self, instance: ConnectionViewModel( - browsingUserUseCase: DIContainer.shared.resolve( - type: BrowsingUserUseCaseInterface.self - ), - openSharedContainerUseCase: DIContainer.shared.resolve( - type: OpenSharedContainerUseCaseInterface.self - ) + usecase: DIContainer.shared.resolve(type: BrowsingUserUseCaseInterface.self) ) ) diff --git a/Data/Data.xcodeproj/project.pbxproj b/Data/Data.xcodeproj/project.pbxproj index cc3d25ec..0dcfdc8c 100644 --- a/Data/Data.xcodeproj/project.pbxproj +++ b/Data/Data.xcodeproj/project.pbxproj @@ -66,7 +66,6 @@ membershipExceptions = ( BrowsingUserRepository.swift, ConnectedUserRepository.swift, - EventRepository.swift, SharingVideoRepository.swift, ); target = FED968292CD9094300CD445C /* Data */; diff --git a/Data/Data/BrowsingUserRepository.swift b/Data/Data/BrowsingUserRepository.swift index a563f6e4..0721c1dc 100644 --- a/Data/Data/BrowsingUserRepository.swift +++ b/Data/Data/BrowsingUserRepository.swift @@ -7,6 +7,7 @@ import Combine import Entity +import Foundation import Interfaces import P2PSocket @@ -16,6 +17,7 @@ public final class BrowsingUserRepository: BrowsingUserRepositoryInterface { public let updatedBrowsingUser = PassthroughSubject() public let updatedInvitedUser = PassthroughSubject() public let invitationReceived = PassthroughSubject() + public let receivedEvent = PassthroughSubject() public init(socketProvider: SocketProvidable) { self.socketProvider = socketProvider @@ -50,6 +52,12 @@ public extension BrowsingUserRepository { func stopReceiveInvitation() { socketProvider.stopReceiveInvitation() } + + func notice(event: OpeningEvent) { + let event = OpeningEvent.sharedContainer + guard let eventData = try? JSONEncoder().encode(event) else { return } + socketProvider.sendAll(data: eventData) + } } // MARK: - Private Methods @@ -75,6 +83,13 @@ private extension BrowsingUserRepository { } .subscribe(invitationReceived) .store(in: &cancellables) + + socketProvider.dataShared + .compactMap { (data, _) in + try? JSONDecoder().decode(OpeningEvent.self, from: data) + }.sink { [weak self] event in + self?.receivedEvent.send(event) + }.store(in: &cancellables) } func mappingToBrowsingUser(_ peer: SocketPeer) -> BrowsedUser? { diff --git a/Domain/Domain.xcodeproj/project.pbxproj b/Domain/Domain.xcodeproj/project.pbxproj index 1c204c55..9ca80304 100644 --- a/Domain/Domain.xcodeproj/project.pbxproj +++ b/Domain/Domain.xcodeproj/project.pbxproj @@ -122,7 +122,6 @@ membershipExceptions = ( BrowsingUserUseCase.swift, ConnectedUserUseCase.swift, - OpenSharedContainerUseCase.swift, VideoUseCase.swift, ); target = FE6EF3C62CD8B5CA005DC39D /* UseCase */; diff --git a/Domain/Entity/Event.swift b/Domain/Entity/OpeningEvent.swift similarity index 55% rename from Domain/Entity/Event.swift rename to Domain/Entity/OpeningEvent.swift index 27d2b4c3..cf0a09fc 100644 --- a/Domain/Entity/Event.swift +++ b/Domain/Entity/OpeningEvent.swift @@ -5,6 +5,6 @@ // Created by Yune gim on 12/2/24. // -public enum Event: Codable { - case openSharedContainer +public enum OpeningEvent: Codable { + case sharedContainer } diff --git a/Domain/Interfaces/RepositoryInterface/BrowsingUserRepositoryInterface.swift b/Domain/Interfaces/RepositoryInterface/BrowsingUserRepositoryInterface.swift index d143de02..691bc458 100644 --- a/Domain/Interfaces/RepositoryInterface/BrowsingUserRepositoryInterface.swift +++ b/Domain/Interfaces/RepositoryInterface/BrowsingUserRepositoryInterface.swift @@ -12,11 +12,13 @@ public protocol BrowsingUserRepositoryInterface { var updatedBrowsingUser: PassthroughSubject { get } var updatedInvitedUser: PassthroughSubject { get } var invitationReceived: PassthroughSubject { get } - + var receivedEvent: PassthroughSubject { get } + func fetchBrowsingUsers() -> [BrowsedUser] func inviteUser(with id: String, timeout: Double) func acceptInvitation() func rejectInvitation() func startReceiveInvitation() func stopReceiveInvitation() + func notice(event: OpeningEvent) } diff --git a/Domain/Interfaces/RepositoryInterface/EventRepositoryInterface.swift b/Domain/Interfaces/RepositoryInterface/EventRepositoryInterface.swift deleted file mode 100644 index d62750e0..00000000 --- a/Domain/Interfaces/RepositoryInterface/EventRepositoryInterface.swift +++ /dev/null @@ -1,15 +0,0 @@ -// -// NoticedEventRepositoryInterface.swift -// Interfaces -// -// Created by Yune gim on 12/2/24. -// - -import Combine -import Entity - -public protocol NoticedEventRepositoryInterface { - var receivedEvent: PassthroughSubject { get } - - func notice(event: Event) -} diff --git a/Domain/Interfaces/RepositoryInterface/OpenSharedContainerRepositoryInterface.swift b/Domain/Interfaces/RepositoryInterface/OpenSharedContainerRepositoryInterface.swift deleted file mode 100644 index b3fbb3f4..00000000 --- a/Domain/Interfaces/RepositoryInterface/OpenSharedContainerRepositoryInterface.swift +++ /dev/null @@ -1,8 +0,0 @@ -// -// OpenSharedContainerRepositoryInterface.swift -// Interfaces -// -// Created by Yune gim on 12/2/24. -// - -import Foundation diff --git a/Domain/Interfaces/UseCaseInterface/BrowsingUserUseCaseInterface.swift b/Domain/Interfaces/UseCaseInterface/BrowsingUserUseCaseInterface.swift index 54e05c81..6466b5e2 100644 --- a/Domain/Interfaces/UseCaseInterface/BrowsingUserUseCaseInterface.swift +++ b/Domain/Interfaces/UseCaseInterface/BrowsingUserUseCaseInterface.swift @@ -17,6 +17,8 @@ public protocol BrowsingUserUseCaseInterface { var invitationReceived: PassthroughSubject { get } /// 초대를 받은 유저가, 초대 시간이 만료되었을 때 stream을 통해 이벤트가 방출됩니다. 초대받은 유저만 이벤트를 받습니다. 초대한 유저의 경우 timeout은 reject이벤트로 옵니다. var invitationDidFired: PassthroughSubject { get } + /// 공유 컨테이너로 화면 전환을 알리는 이벤트를 방출합니다. + var openingEvent: PassthroughSubject { get } init(repository: BrowsingUserRepositoryInterface, invitationTimeout: Double) @@ -24,4 +26,5 @@ public protocol BrowsingUserUseCaseInterface { func inviteUser(with id: String) func acceptInvitation() func rejectInvitation() + func noticeOpening() } diff --git a/Domain/Interfaces/UseCaseInterface/OpenSharedContainerUseCaseInterface.swift b/Domain/Interfaces/UseCaseInterface/OpenSharedContainerUseCaseInterface.swift deleted file mode 100644 index e65284a8..00000000 --- a/Domain/Interfaces/UseCaseInterface/OpenSharedContainerUseCaseInterface.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// OpenSharedContainerUseCaseInterface.swift -// Interfaces -// -// Created by Yune gim on 12/2/24. -// - -import Combine - -public protocol OpenSharedContainerUseCaseInterface { - var openEvent: PassthroughSubject { get } - - func noticeOpening() -} diff --git a/Domain/UseCase/BrowsingUserUseCase.swift b/Domain/UseCase/BrowsingUserUseCase.swift index 86af938a..7c815b4d 100644 --- a/Domain/UseCase/BrowsingUserUseCase.swift +++ b/Domain/UseCase/BrowsingUserUseCase.swift @@ -24,6 +24,7 @@ public final class BrowsingUserUseCase: BrowsingUserUseCaseInterface { public let invitationResult = PassthroughSubject() public let invitationReceived = PassthroughSubject() public let invitationDidFired = PassthroughSubject() + public var openingEvent = PassthroughSubject() public init(repository: BrowsingUserRepositoryInterface, invitationTimeout: Double = 30.0) { self.repository = repository @@ -57,6 +58,11 @@ public extension BrowsingUserUseCase { repository.startReceiveInvitation() repository.rejectInvitation() } + + func noticeOpening() { + repository.notice(event: OpeningEvent.sharedContainer) + openingEvent.send() + } } // MARK: - Private Methods @@ -79,6 +85,12 @@ private extension BrowsingUserUseCase { self?.invitationDidReceive(from: user) } .store(in: &cancellables) + repository.receivedEvent + .sink { [weak self] event in + guard event == .sharedContainer else { return } + self?.openingEvent.send() + } + .store(in: &cancellables) } func receivedBrowsedUser(_ user: BrowsedUser) { diff --git a/Domain/UseCase/OpenSharedContainerUseCase.swift b/Domain/UseCase/OpenSharedContainerUseCase.swift deleted file mode 100644 index e5fe2335..00000000 --- a/Domain/UseCase/OpenSharedContainerUseCase.swift +++ /dev/null @@ -1,43 +0,0 @@ -// -// OpenSharedContainerUseCase.swift -// UseCase -// -// Created by Yune gim on 12/2/24. -// - -import Combine -import Entity -import Interfaces - -public final class OpenSharedContainerUseCase: OpenSharedContainerUseCaseInterface { - private let repository: NoticedEventRepositoryInterface - private var cancellables: Set = [] - - public var openEvent = PassthroughSubject() - - public init(repository: NoticedEventRepositoryInterface) { - self.repository = repository - bind() - } -} - -// MARK: - Public Methods -public extension OpenSharedContainerUseCase { - func noticeOpening() { - repository.notice(event: Event.openSharedContainer) - openEvent.send() - } -} - -// MARK: - Private Methods -private extension OpenSharedContainerUseCase { - func bind() { - repository.receivedEvent - .sink { [weak self] event in - if event == .openSharedContainer { - self?.openEvent.send() - } - } - .store(in: &cancellables) - } -} diff --git a/Feature/Feature/ConnectionView/ViewModel/ConnectionViewModel.swift b/Feature/Feature/ConnectionView/ViewModel/ConnectionViewModel.swift index b99f25df..6046ffe0 100644 --- a/Feature/Feature/ConnectionView/ViewModel/ConnectionViewModel.swift +++ b/Feature/Feature/ConnectionView/ViewModel/ConnectionViewModel.swift @@ -18,8 +18,7 @@ final public class ConnectionViewModel { // MARK: - Properties - private let browsingUserUseCase: BrowsingUserUseCaseInterface - private let openSharedContainerUseCase: OpenSharedContainerUseCaseInterface + private let usecase: BrowsingUserUseCaseInterface private var output = PassthroughSubject() private var cancellables: Set = [] @@ -30,10 +29,8 @@ final public class ConnectionViewModel { // MARK: - Initializer - public init(browsingUserUseCase: BrowsingUserUseCaseInterface, - openSharedContainerUseCase: OpenSharedContainerUseCaseInterface) { - self.browsingUserUseCase = browsingUserUseCase - self.openSharedContainerUseCase = openSharedContainerUseCase + public init(usecase: BrowsingUserUseCaseInterface) { + self.usecase = usecase setupBind() } @@ -64,19 +61,19 @@ extension ConnectionViewModel { // Connection Input case .fetchUsers: - browsingUserUseCase.fetchBrowsedUsers().forEach({ self.found(user: $0) }) + usecase.fetchBrowsedUsers().forEach({ self.found(user: $0) }) case .inviteUser(let id): - browsingUserUseCase.inviteUser(with: id) + usecase.inviteUser(with: id) // Invitation Input case .acceptInvitation(let user): - browsingUserUseCase.acceptInvitation() + usecase.acceptInvitation() removeCurrentPosition(id: user.id) case .rejectInvitation: - browsingUserUseCase.rejectInvitation() + usecase.rejectInvitation() case .nextButtonDidTapped: - openSharedContainerUseCase.noticeOpening() + usecase.noticeOpening() } } .store(in: &cancellables) @@ -91,7 +88,7 @@ private extension ConnectionViewModel { func setupBind() { // Broswed User (found, lost) - browsingUserUseCase.browsedUser + usecase.browsedUser .sink { [weak self] updatedUser in guard let self else { return } @@ -106,7 +103,7 @@ private extension ConnectionViewModel { // Invitation Received (From Who) - browsingUserUseCase.invitationReceived + usecase.invitationReceived .sink { [weak self] invitingUser in guard let self else { return } output.send(.invitationReceivedBy(user: invitingUser)) @@ -115,7 +112,7 @@ private extension ConnectionViewModel { // Invitation Result (when I invite other users) - browsingUserUseCase.invitationResult + usecase.invitationResult .sink { [weak self] invitedUser in guard let self else { return } @@ -135,16 +132,16 @@ private extension ConnectionViewModel { // Invitaion Fired Due to Timeout (invited user receive) - browsingUserUseCase.invitationDidFired + usecase.invitationDidFired .sink { [weak self] in guard let self else { return } output.send(.invitationTimeout) - browsingUserUseCase.rejectInvitation() + usecase.rejectInvitation() } .store(in: &cancellables) - openSharedContainerUseCase.openEvent + usecase.openingEvent .sink { [weak self] in guard let self else { return } output.send(.openSharedVideoList) From cebfe91c96f1b2a7a61da8c28e23c0be709adaf1 Mon Sep 17 00:00:00 2001 From: 051198Hz Date: Mon, 2 Dec 2024 20:55:37 +0900 Subject: [PATCH 9/9] =?UTF-8?q?[REFACTOR]:=20EventRepository=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Data/Data/EventRepository.swift | 39 --------------------------------- 1 file changed, 39 deletions(-) delete mode 100644 Data/Data/EventRepository.swift diff --git a/Data/Data/EventRepository.swift b/Data/Data/EventRepository.swift deleted file mode 100644 index b3b9c884..00000000 --- a/Data/Data/EventRepository.swift +++ /dev/null @@ -1,39 +0,0 @@ -// -// NoticedEventRepository.swift -// Data -// -// Created by Yune gim on 12/2/24. -// - -import Combine -import Entity -import Foundation -import Interfaces -import P2PSocket - -public final class NoticedEventRepository: NoticedEventRepositoryInterface { - private var cancellables: Set = [] - private let socketProvider: SocketProvidable - - public var receivedEvent = PassthroughSubject() - - public init(socketProvider: SocketProvidable) { - self.socketProvider = socketProvider - bind() - } - - public func notice(event: Event) { - guard let eventData = try? JSONEncoder().encode(event) else { return } - socketProvider.sendAll(data: eventData) - } -} - -private extension NoticedEventRepository { - func bind() { - socketProvider.dataShared.sink { [weak self] (data, _) in - guard let event = try? JSONDecoder().decode(Event.self, from: data) else { return } - self?.receivedEvent.send(event) - } - .store(in: &cancellables) - } -}