From 9a04f1c290acdba45d933003d03f7c2862aecdc8 Mon Sep 17 00:00:00 2001 From: taipaise Date: Mon, 30 Dec 2024 20:36:48 +0900 Subject: [PATCH 1/7] =?UTF-8?q?refactor:=20NearbyNetworkInterface=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=84=B0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Interface/NearbyNetworkInterface.swift | 9 ++++++++ .../Sources/Model/NetworkConnection.swift | 22 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/DataSource/DataSource/Sources/Interface/NearbyNetworkInterface.swift b/DataSource/DataSource/Sources/Interface/NearbyNetworkInterface.swift index 786d4c6..5de3962 100644 --- a/DataSource/DataSource/Sources/Interface/NearbyNetworkInterface.swift +++ b/DataSource/DataSource/Sources/Interface/NearbyNetworkInterface.swift @@ -21,8 +21,15 @@ public protocol NearbyNetworkInterface { /// 주변에 내 기기를 정보와 함께 알립니다. /// - Parameter data: 담을 정보 + @available(*, deprecated, message: "이 메서드는 network framework로 리팩터링 하면서 사용되지 않을 예정입니다.") func startPublishing(with info: [String: String]) + /// 주변에 내 기기를 정보와 함께 알립니다. + /// - Parameters: + /// - hostName: 호스트의 이름 + /// - connectedPeerInfo: 연결된 기기들의 정보 + func startPublishing(with hostName: String, connectedPeerInfo: [String]) + /// 주변에 내 기기 알리는 것을 중지합니다. func stopPublishing() @@ -41,6 +48,7 @@ public protocol NearbyNetworkInterface { /// - Parameters: /// - fileURL: 파일의 URL /// - info: 파일에 대한 정보 + @available(*, deprecated, message: "이 메서드는 network framework로 리팩터링 하면서 사용되지 않을 예정입니다.") func send(fileURL: URL, info: DataInformationDTO) async /// 특정 기기에게 파일을 전송합니다. @@ -48,6 +56,7 @@ public protocol NearbyNetworkInterface { /// - fileURL: 파일의 URL /// - info: 파일에 대한 정보 /// - connection: 전송할 기기 연결 정보 + @available(*, deprecated, message: "이 메서드는 network framework로 리팩터링 하면서 사용되지 않을 예정입니다.") func send( fileURL: URL, info: DataSource.DataInformationDTO, diff --git a/DataSource/DataSource/Sources/Model/NetworkConnection.swift b/DataSource/DataSource/Sources/Model/NetworkConnection.swift index d58f07a..e37a51d 100644 --- a/DataSource/DataSource/Sources/Model/NetworkConnection.swift +++ b/DataSource/DataSource/Sources/Model/NetworkConnection.swift @@ -28,3 +28,25 @@ extension NetworkConnection: Equatable { return lhs.id == rhs.id } } + +public struct RefactoredNetworkConnection: Codable { + public let id: UUID + public let name: String + public let connectedPeerInfo: [String] + + public init( + id: UUID, + name: String, + connectedPeerInfo: [String] + ) { + self.id = id + self.name = name + self.connectedPeerInfo = connectedPeerInfo + } +} + +extension RefactoredNetworkConnection: Equatable { + public static func == (lhs: RefactoredNetworkConnection, rhs: RefactoredNetworkConnection) -> Bool { + return lhs.id == rhs.id + } +} From a9ee5990e4ea8e822823e246450509e19343b554 Mon Sep 17 00:00:00 2001 From: taipaise Date: Mon, 30 Dec 2024 20:38:15 +0900 Subject: [PATCH 2/7] =?UTF-8?q?refactor:=20advertising=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EB=A6=AC=ED=8C=A9=ED=84=B0=EB=A7=81(#143)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/Model/DataInformationDTO.swift | 10 ++ .../NearbyNetwork.xcodeproj/project.pbxproj | 4 + .../Sources/NearbyNetworkService.swift | 4 + .../RefactoredNearbyNetworkService.swift | 94 +++++++++++++++++++ 4 files changed, 112 insertions(+) create mode 100644 NearbyNetwork/NearbyNetwork/Sources/RefactoredNearbyNetworkService.swift diff --git a/DataSource/DataSource/Sources/Model/DataInformationDTO.swift b/DataSource/DataSource/Sources/Model/DataInformationDTO.swift index a57e334..6edf11b 100644 --- a/DataSource/DataSource/Sources/Model/DataInformationDTO.swift +++ b/DataSource/DataSource/Sources/Model/DataInformationDTO.swift @@ -11,4 +11,14 @@ public struct DataInformationDTO: Codable { public let id: UUID public let type: AirplaINDataType public let isDeleted: Bool + + public init( + id: UUID, + type: AirplaINDataType, + isDeleted: Bool + ) { + self.id = id + self.type = type + self.isDeleted = isDeleted + } } diff --git a/NearbyNetwork/NearbyNetwork.xcodeproj/project.pbxproj b/NearbyNetwork/NearbyNetwork.xcodeproj/project.pbxproj index 00c5227..73fbaf6 100644 --- a/NearbyNetwork/NearbyNetwork.xcodeproj/project.pbxproj +++ b/NearbyNetwork/NearbyNetwork.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 002DEC952D22A99F00ED7EE3 /* RefactoredNearbyNetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 002DEC942D22A99F00ED7EE3 /* RefactoredNearbyNetworkService.swift */; }; 00549AD62CEDDDB700DF8F6C /* MCSessionState+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00549AD52CEDDDB100DF8F6C /* MCSessionState+.swift */; }; 00549AD82CEDDDCF00DF8F6C /* MCSession+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00549AD72CEDDDCF00DF8F6C /* MCSession+.swift */; }; 0080E86A2CE19EC40095B958 /* NearbyNetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0080E8672CE19EC40095B958 /* NearbyNetworkService.swift */; }; @@ -29,6 +30,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 002DEC942D22A99F00ED7EE3 /* RefactoredNearbyNetworkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefactoredNearbyNetworkService.swift; sourceTree = ""; }; 00549AD52CEDDDB100DF8F6C /* MCSessionState+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MCSessionState+.swift"; sourceTree = ""; }; 00549AD72CEDDDCF00DF8F6C /* MCSession+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MCSession+.swift"; sourceTree = ""; }; 0080E8672CE19EC40095B958 /* NearbyNetworkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearbyNetworkService.swift; sourceTree = ""; }; @@ -70,6 +72,7 @@ children = ( 00549AD32CEDDDA300DF8F6C /* Common */, 0080E8672CE19EC40095B958 /* NearbyNetworkService.swift */, + 002DEC942D22A99F00ED7EE3 /* RefactoredNearbyNetworkService.swift */, ); path = Sources; sourceTree = ""; @@ -214,6 +217,7 @@ files = ( 00549AD62CEDDDB700DF8F6C /* MCSessionState+.swift in Sources */, 00549AD82CEDDDCF00DF8F6C /* MCSession+.swift in Sources */, + 002DEC952D22A99F00ED7EE3 /* RefactoredNearbyNetworkService.swift in Sources */, 0080E86A2CE19EC40095B958 /* NearbyNetworkService.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkService.swift b/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkService.swift index 571c6e2..b8e2dd5 100644 --- a/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkService.swift +++ b/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkService.swift @@ -76,6 +76,10 @@ extension NearbyNetworkService: NearbyNetworkInterface { serviceAdvertiser.startAdvertisingPeer() } + public func startPublishing(with hostName: String, connectedPeerInfo: [String]) { + // TODO: - 사용하지 않는 함수 + } + public func stopPublishing() { serviceAdvertiser.stopAdvertisingPeer() } diff --git a/NearbyNetwork/NearbyNetwork/Sources/RefactoredNearbyNetworkService.swift b/NearbyNetwork/NearbyNetwork/Sources/RefactoredNearbyNetworkService.swift new file mode 100644 index 0000000..0b3b504 --- /dev/null +++ b/NearbyNetwork/NearbyNetwork/Sources/RefactoredNearbyNetworkService.swift @@ -0,0 +1,94 @@ +// +// RefactoredNearbyNetworkService.swift +// NearbyNetwork +// +// Created by 이동현 on 12/30/24. +// + +import Combine +import DataSource +import Foundation +import Network + +// TODO: - 추후 기능 동작 확인 후 NearbyNetworkService 대체 +final class RefactoredNearbyNetworkService { + var connectionDelegate: NearbyNetworkConnectionDelegate? = nil + private let peerID: UUID + private let nwListener: NWListener + private let networkQueue: DispatchQueue + + public init(serviceName: String) throws { + peerID = UUID() + + do { + nwListener = try NWListener(using: .tcp) + networkQueue = DispatchQueue.global() + } catch { + throw NSError() // 에러는 추후 정의 + } + } +} + +extension RefactoredNearbyNetworkService: NearbyNetworkInterface { + var reciptDataPublisher: AnyPublisher { + return Just(Data()).eraseToAnyPublisher() + } + + var reciptURLPublisher: AnyPublisher<(url: URL, dataInfo: DataInformationDTO), Never> { + // TODO: - will be deprecated + guard let url = URL(string: "https://naver.com") else { fatalError() } + let dataInfo = DataInformationDTO( + id: UUID(), + type: .chat, + isDeleted: true) + return Just<(url: URL, dataInfo: DataInformationDTO)>((url: url, dataInfo: dataInfo)) + .eraseToAnyPublisher() + } + + func stopSearching() { + + } + + func startSearching() { + + } + + func startPublishing(with info: [String: String]) { + // TODO: - will be deprecated + } + + func startPublishing(with hostName: String, connectedPeerInfo: [String]) { + let networkConnection = RefactoredNetworkConnection( + id: peerID, + name: hostName, + connectedPeerInfo: connectedPeerInfo) + let serviceData = try? JSONEncoder().encode(networkConnection) + + nwListener.service? = NWListener.Service(type: "_airplain._tcp", txtRecord: serviceData) + nwListener.start(queue: networkQueue) + } + + func stopPublishing() { + + } + + func disconnectAll() { + + } + + func joinConnection(connection: NetworkConnection, context: RequestedContext) throws { + + } + + func send(data: Data) { + + } + + func send(fileURL: URL, info: DataInformationDTO) async { + // TODO: - will be deprecated + } + + func send(fileURL: URL, info: DataInformationDTO, to connection: NetworkConnection) async { + // TODO: - will be deprecated + } +} From 562bed2bec59bf9939f18a40e58ba8860ba9efd6 Mon Sep 17 00:00:00 2001 From: taipaise Date: Mon, 30 Dec 2024 20:40:54 +0900 Subject: [PATCH 3/7] =?UTF-8?q?refactor:=20advertising=20=EC=A4=91?= =?UTF-8?q?=EC=A7=80=20=EA=B8=B0=EB=8A=A5=20=EB=A6=AC=ED=8C=A9=ED=84=B0?= =?UTF-8?q?=EB=A7=81(#143)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NearbyNetwork/Sources/RefactoredNearbyNetworkService.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NearbyNetwork/NearbyNetwork/Sources/RefactoredNearbyNetworkService.swift b/NearbyNetwork/NearbyNetwork/Sources/RefactoredNearbyNetworkService.swift index 0b3b504..c6199e7 100644 --- a/NearbyNetwork/NearbyNetwork/Sources/RefactoredNearbyNetworkService.swift +++ b/NearbyNetwork/NearbyNetwork/Sources/RefactoredNearbyNetworkService.swift @@ -69,7 +69,7 @@ extension RefactoredNearbyNetworkService: NearbyNetworkInterface { } func stopPublishing() { - + nwListener.cancel() } func disconnectAll() { From 9df65502676b02a013ef214ffe56ab4d55ab27cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8E=E1=85=AC=E1=84=8C=E1=85=A5=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Tue, 31 Dec 2024 15:07:58 +0900 Subject: [PATCH 4/7] =?UTF-8?q?refactor:=20NearbyNetworkListener=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=84=B0=EB=A7=81(#144)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/NearbyNetworkKey.swift | 11 ++++ .../Sources/NearbyNetworkListener.swift | 62 +++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkKey.swift create mode 100644 NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkListener.swift diff --git a/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkKey.swift b/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkKey.swift new file mode 100644 index 0000000..08a5dc3 --- /dev/null +++ b/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkKey.swift @@ -0,0 +1,11 @@ +// +// NearbyNetworkKey.swift +// NearbyNetwork +// +// Created by 최정인 on 12/31/24. +// + +enum NearbyNetworkKey: String { + case host + case connectedPeerInfo +} diff --git a/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkListener.swift b/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkListener.swift new file mode 100644 index 0000000..0b47019 --- /dev/null +++ b/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkListener.swift @@ -0,0 +1,62 @@ +// +// NearbyNetworkListener.swift +// NearbyNetwork +// +// Created by 최정인 on 12/31/24. +// + +import Foundation +import Network +import OSLog + +final class NearbyNetworkListener { + var nwListener: NWListener? + private let listenerQueue: DispatchQueue + private let serviceName: String + private let serviceType: String + private let logger: Logger + + init(serviceName: String, serviceType: String) { + nwListener = try? NWListener(using: .tcp) + listenerQueue = DispatchQueue.global() + self.serviceName = serviceName + self.serviceType = serviceType + self.logger = Logger() + configure() + } + + private func configure() { + nwListener?.newConnectionHandler = { connection in + connection.start(queue: self.listenerQueue) + } + } + + func startPublishing(hostName: String, connectedPeerInfo: [String]) { + let connectionData = [ + NearbyNetworkKey.host.rawValue: hostName, + NearbyNetworkKey.connectedPeerInfo.rawValue: connectedPeerInfo.joined(separator: ",")] + let txtRecord = NWTXTRecord(connectionData) + + nwListener?.service = NWListener.Service( + name: serviceName, + type: serviceType, + txtRecord: txtRecord) + + nwListener?.stateUpdateHandler = { state in + switch state { + case .ready: + self.logger.log(level: .debug, "NWListener READY") + case .failed(let error): + self.logger.log(level: .error, "NWListener Failed \(error.localizedDescription)") + default: + break + } + } + + nwListener?.start(queue: listenerQueue) + } + + func stopPublishing() { + nwListener?.cancel() + } +} From 09b7df624f0068914b130bb8b7a36119f8fba03a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8E=E1=85=AC=E1=84=8C=E1=85=A5=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Tue, 31 Dec 2024 15:09:35 +0900 Subject: [PATCH 5/7] =?UTF-8?q?refactor:=20NearbyNetworkService=20?= =?UTF-8?q?=EC=97=AD=ED=95=A0=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NearbyNetwork.xcodeproj/project.pbxproj | 12 +++++ .../Sources/NearbyNetworkBrowser.swift | 51 +++++++++++++++++++ .../RefactoredNearbyNetworkService.swift | 45 ++++++++-------- 3 files changed, 85 insertions(+), 23 deletions(-) create mode 100644 NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkBrowser.swift diff --git a/NearbyNetwork/NearbyNetwork.xcodeproj/project.pbxproj b/NearbyNetwork/NearbyNetwork.xcodeproj/project.pbxproj index 73fbaf6..6c06339 100644 --- a/NearbyNetwork/NearbyNetwork.xcodeproj/project.pbxproj +++ b/NearbyNetwork/NearbyNetwork.xcodeproj/project.pbxproj @@ -13,6 +13,9 @@ 0080E86A2CE19EC40095B958 /* NearbyNetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0080E8672CE19EC40095B958 /* NearbyNetworkService.swift */; }; 5B7C6EBF2CDB6C6E0024704A /* DataSource.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B7C6EBE2CDB6C6E0024704A /* DataSource.framework */; }; 5B7C6EC02CDB6C6E0024704A /* DataSource.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 5B7C6EBE2CDB6C6E0024704A /* DataSource.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + A83D2AB02D23BAFC007EC41F /* NearbyNetworkListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = A83D2AAF2D23BAFC007EC41F /* NearbyNetworkListener.swift */; }; + A83D2AB22D23BE88007EC41F /* NearbyNetworkBrowser.swift in Sources */ = {isa = PBXBuildFile; fileRef = A83D2AB12D23BE88007EC41F /* NearbyNetworkBrowser.swift */; }; + A83D2AB42D23C09F007EC41F /* NearbyNetworkKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = A83D2AB32D23C09F007EC41F /* NearbyNetworkKey.swift */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -36,6 +39,9 @@ 0080E8672CE19EC40095B958 /* NearbyNetworkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearbyNetworkService.swift; sourceTree = ""; }; 5B7C6E652CDB6A560024704A /* NearbyNetwork.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = NearbyNetwork.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 5B7C6EBE2CDB6C6E0024704A /* DataSource.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = DataSource.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + A83D2AAF2D23BAFC007EC41F /* NearbyNetworkListener.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearbyNetworkListener.swift; sourceTree = ""; }; + A83D2AB12D23BE88007EC41F /* NearbyNetworkBrowser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearbyNetworkBrowser.swift; sourceTree = ""; }; + A83D2AB32D23C09F007EC41F /* NearbyNetworkKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearbyNetworkKey.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -73,6 +79,9 @@ 00549AD32CEDDDA300DF8F6C /* Common */, 0080E8672CE19EC40095B958 /* NearbyNetworkService.swift */, 002DEC942D22A99F00ED7EE3 /* RefactoredNearbyNetworkService.swift */, + A83D2AAF2D23BAFC007EC41F /* NearbyNetworkListener.swift */, + A83D2AB32D23C09F007EC41F /* NearbyNetworkKey.swift */, + A83D2AB12D23BE88007EC41F /* NearbyNetworkBrowser.swift */, ); path = Sources; sourceTree = ""; @@ -215,10 +224,13 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + A83D2AB22D23BE88007EC41F /* NearbyNetworkBrowser.swift in Sources */, 00549AD62CEDDDB700DF8F6C /* MCSessionState+.swift in Sources */, + A83D2AB02D23BAFC007EC41F /* NearbyNetworkListener.swift in Sources */, 00549AD82CEDDDCF00DF8F6C /* MCSession+.swift in Sources */, 002DEC952D22A99F00ED7EE3 /* RefactoredNearbyNetworkService.swift in Sources */, 0080E86A2CE19EC40095B958 /* NearbyNetworkService.swift in Sources */, + A83D2AB42D23C09F007EC41F /* NearbyNetworkKey.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkBrowser.swift b/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkBrowser.swift new file mode 100644 index 0000000..3bee36b --- /dev/null +++ b/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkBrowser.swift @@ -0,0 +1,51 @@ +// +// NearbyNetworkBrowser.swift +// NearbyNetwork +// +// Created by 최정인 on 12/31/24. +// + +import Foundation +import Network +import OSLog + +final class NearbyNetworkBrowser { + let nwBrowser: NWBrowser + private let browserQueue: DispatchQueue + private let serviceType: String + private let logger: Logger + + init(serviceType: String) { + nwBrowser = NWBrowser( + for: .bonjourWithTXTRecord(type: serviceType, domain: nil), + using: .tcp) + self.browserQueue = DispatchQueue.global() + self.serviceType = serviceType + self.logger = Logger() + configure() + } + + private func configure() { + nwBrowser.browseResultsChangedHandler = browserHandler + } + + private func browserHandler(results: Set, changes: Set) { + for result in results { + switch result.metadata { + case .bonjour(let foundedPeerData): + // TODO: - 추후 발견한 데이터 이용 + print("") + default: + logger.log(level: .error, "알 수 없는 피어가 발견되었습니다.") + } + } + } + + func startSearching() { + nwBrowser.start(queue: browserQueue) + } + + func stopSearching() { + nwBrowser.cancel() + } +} diff --git a/NearbyNetwork/NearbyNetwork/Sources/RefactoredNearbyNetworkService.swift b/NearbyNetwork/NearbyNetwork/Sources/RefactoredNearbyNetworkService.swift index c6199e7..5f1f70e 100644 --- a/NearbyNetwork/NearbyNetwork/Sources/RefactoredNearbyNetworkService.swift +++ b/NearbyNetwork/NearbyNetwork/Sources/RefactoredNearbyNetworkService.swift @@ -9,23 +9,27 @@ import Combine import DataSource import Foundation import Network +import OSLog // TODO: - 추후 기능 동작 확인 후 NearbyNetworkService 대체 final class RefactoredNearbyNetworkService { var connectionDelegate: NearbyNetworkConnectionDelegate? = nil + private let serviceName: String + private let serviceType: String private let peerID: UUID - private let nwListener: NWListener - private let networkQueue: DispatchQueue + private let nearbyNetworkListener: NearbyNetworkListener + private let nearbyNetworkBrowser: NearbyNetworkBrowser + private let logger: Logger - public init(serviceName: String) throws { + public init(serviceName: String, serviceType: String) throws { peerID = UUID() - - do { - nwListener = try NWListener(using: .tcp) - networkQueue = DispatchQueue.global() - } catch { - throw NSError() // 에러는 추후 정의 - } + logger = Logger() + nearbyNetworkListener = NearbyNetworkListener( + serviceName: serviceName, + serviceType: serviceType) + nearbyNetworkBrowser = NearbyNetworkBrowser(serviceType: serviceType) + self.serviceName = serviceName + self.serviceType = serviceType } } @@ -33,7 +37,7 @@ extension RefactoredNearbyNetworkService: NearbyNetworkInterface { var reciptDataPublisher: AnyPublisher { return Just(Data()).eraseToAnyPublisher() } - + var reciptURLPublisher: AnyPublisher<(url: URL, dataInfo: DataInformationDTO), Never> { // TODO: - will be deprecated guard let url = URL(string: "https://naver.com") else { fatalError() } @@ -45,12 +49,12 @@ extension RefactoredNearbyNetworkService: NearbyNetworkInterface { .eraseToAnyPublisher() } - func stopSearching() { - - } - func startSearching() { + nearbyNetworkBrowser.startSearching() + } + func stopSearching() { + nearbyNetworkBrowser.stopSearching() } func startPublishing(with info: [String: String]) { @@ -58,18 +62,13 @@ extension RefactoredNearbyNetworkService: NearbyNetworkInterface { } func startPublishing(with hostName: String, connectedPeerInfo: [String]) { - let networkConnection = RefactoredNetworkConnection( - id: peerID, - name: hostName, + nearbyNetworkListener.startPublishing( + hostName: hostName, connectedPeerInfo: connectedPeerInfo) - let serviceData = try? JSONEncoder().encode(networkConnection) - - nwListener.service? = NWListener.Service(type: "_airplain._tcp", txtRecord: serviceData) - nwListener.start(queue: networkQueue) } func stopPublishing() { - nwListener.cancel() + nearbyNetworkListener.stopPublishing() } func disconnectAll() { From d11b5fe0d475799f19c66bf8f9e5d8b20dd1cd94 Mon Sep 17 00:00:00 2001 From: taipaise Date: Tue, 31 Dec 2024 16:28:51 +0900 Subject: [PATCH 6/7] =?UTF-8?q?feature:=20=EA=B7=BC=EA=B1=B0=EB=A6=AC=20?= =?UTF-8?q?=ED=86=B5=EC=8B=A0=20=EB=AA=A8=EB=93=88=20=EA=B4=91=EA=B3=A0,?= =?UTF-8?q?=20=EA=B2=80=EC=83=89=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NearbyNetwork.xcodeproj/project.pbxproj | 122 ++++++++++++++++++ .../Sources/NearbyNetworkBrowser.swift | 27 +++- .../Sources/NearbyNetworkKey.swift | 2 +- .../RefactoredNearbyNetworkService.swift | 45 ++++--- .../NearbyNetworkTests.swift | 118 +++++++++++++++++ 5 files changed, 295 insertions(+), 19 deletions(-) create mode 100644 NearbyNetwork/NearbyNetworkTests/NearbyNetworkTests.swift diff --git a/NearbyNetwork/NearbyNetwork.xcodeproj/project.pbxproj b/NearbyNetwork/NearbyNetwork.xcodeproj/project.pbxproj index 6c06339..0840798 100644 --- a/NearbyNetwork/NearbyNetwork.xcodeproj/project.pbxproj +++ b/NearbyNetwork/NearbyNetwork.xcodeproj/project.pbxproj @@ -8,6 +8,8 @@ /* Begin PBXBuildFile section */ 002DEC952D22A99F00ED7EE3 /* RefactoredNearbyNetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 002DEC942D22A99F00ED7EE3 /* RefactoredNearbyNetworkService.swift */; }; + 002DEC9D2D23C33C00ED7EE3 /* NearbyNetworkTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 002DEC9C2D23C33C00ED7EE3 /* NearbyNetworkTests.swift */; }; + 002DEC9E2D23C33C00ED7EE3 /* NearbyNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B7C6E652CDB6A560024704A /* NearbyNetwork.framework */; platformFilter = ios; }; 00549AD62CEDDDB700DF8F6C /* MCSessionState+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00549AD52CEDDDB100DF8F6C /* MCSessionState+.swift */; }; 00549AD82CEDDDCF00DF8F6C /* MCSession+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00549AD72CEDDDCF00DF8F6C /* MCSession+.swift */; }; 0080E86A2CE19EC40095B958 /* NearbyNetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0080E8672CE19EC40095B958 /* NearbyNetworkService.swift */; }; @@ -18,6 +20,16 @@ A83D2AB42D23C09F007EC41F /* NearbyNetworkKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = A83D2AB32D23C09F007EC41F /* NearbyNetworkKey.swift */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 002DEC9F2D23C33C00ED7EE3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 5B7C6E5C2CDB6A560024704A /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5B7C6E642CDB6A560024704A; + remoteInfo = NearbyNetwork; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXCopyFilesBuildPhase section */ 5B7C6EC12CDB6C6E0024704A /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; @@ -34,6 +46,8 @@ /* Begin PBXFileReference section */ 002DEC942D22A99F00ED7EE3 /* RefactoredNearbyNetworkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefactoredNearbyNetworkService.swift; sourceTree = ""; }; + 002DEC9A2D23C33C00ED7EE3 /* NearbyNetworkTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NearbyNetworkTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 002DEC9C2D23C33C00ED7EE3 /* NearbyNetworkTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearbyNetworkTests.swift; sourceTree = ""; }; 00549AD52CEDDDB100DF8F6C /* MCSessionState+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MCSessionState+.swift"; sourceTree = ""; }; 00549AD72CEDDDCF00DF8F6C /* MCSession+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MCSession+.swift"; sourceTree = ""; }; 0080E8672CE19EC40095B958 /* NearbyNetworkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearbyNetworkService.swift; sourceTree = ""; }; @@ -45,6 +59,14 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 002DEC972D23C33C00ED7EE3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 002DEC9E2D23C33C00ED7EE3 /* NearbyNetwork.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5B7C6E622CDB6A560024704A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -56,6 +78,14 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 002DEC9B2D23C33C00ED7EE3 /* NearbyNetworkTests */ = { + isa = PBXGroup; + children = ( + 002DEC9C2D23C33C00ED7EE3 /* NearbyNetworkTests.swift */, + ); + path = NearbyNetworkTests; + sourceTree = ""; + }; 00549AD32CEDDDA300DF8F6C /* Common */ = { isa = PBXGroup; children = ( @@ -98,6 +128,7 @@ isa = PBXGroup; children = ( 0080E8692CE19EC40095B958 /* NearbyNetwork */, + 002DEC9B2D23C33C00ED7EE3 /* NearbyNetworkTests */, 5B7C6EBD2CDB6C6E0024704A /* Frameworks */, 5B7C6E662CDB6A560024704A /* Products */, ); @@ -107,6 +138,7 @@ isa = PBXGroup; children = ( 5B7C6E652CDB6A560024704A /* NearbyNetwork.framework */, + 002DEC9A2D23C33C00ED7EE3 /* NearbyNetworkTests.xctest */, ); name = Products; sourceTree = ""; @@ -132,6 +164,24 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ + 002DEC992D23C33C00ED7EE3 /* NearbyNetworkTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 002DECA32D23C33C00ED7EE3 /* Build configuration list for PBXNativeTarget "NearbyNetworkTests" */; + buildPhases = ( + 002DEC962D23C33C00ED7EE3 /* Sources */, + 002DEC972D23C33C00ED7EE3 /* Frameworks */, + 002DEC982D23C33C00ED7EE3 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 002DECA02D23C33C00ED7EE3 /* PBXTargetDependency */, + ); + name = NearbyNetworkTests; + productName = NearbyNetworkTests; + productReference = 002DEC9A2D23C33C00ED7EE3 /* NearbyNetworkTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 5B7C6E642CDB6A560024704A /* NearbyNetwork */ = { isa = PBXNativeTarget; buildConfigurationList = 5B7C6E6B2CDB6A560024704A /* Build configuration list for PBXNativeTarget "NearbyNetwork" */; @@ -161,8 +211,12 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1540; LastUpgradeCheck = 1600; TargetAttributes = { + 002DEC992D23C33C00ED7EE3 = { + CreatedOnToolsVersion = 15.4; + }; 5B7C6E642CDB6A560024704A = { CreatedOnToolsVersion = 16.0; LastSwiftMigration = 1600; @@ -184,11 +238,19 @@ projectRoot = ""; targets = ( 5B7C6E642CDB6A560024704A /* NearbyNetwork */, + 002DEC992D23C33C00ED7EE3 /* NearbyNetworkTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 002DEC982D23C33C00ED7EE3 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5B7C6E632CDB6A560024704A /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -220,6 +282,14 @@ /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 002DEC962D23C33C00ED7EE3 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 002DEC9D2D23C33C00ED7EE3 /* NearbyNetworkTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 5B7C6E612CDB6A560024704A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -236,7 +306,50 @@ }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + 002DECA02D23C33C00ED7EE3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + platformFilter = ios; + target = 5B7C6E642CDB6A560024704A /* NearbyNetwork */; + targetProxy = 002DEC9F2D23C33C00ED7EE3 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin XCBuildConfiguration section */ + 002DECA12D23C33C00ED7EE3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = VKW8W27KRV; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = kr.codesquad.boostcamp9.NearbyNetworkTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 002DECA22D23C33C00ED7EE3 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = VKW8W27KRV; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = kr.codesquad.boostcamp9.NearbyNetworkTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; 5B7C6E6C2CDB6A560024704A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -446,6 +559,15 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 002DECA32D23C33C00ED7EE3 /* Build configuration list for PBXNativeTarget "NearbyNetworkTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 002DECA12D23C33C00ED7EE3 /* Debug */, + 002DECA22D23C33C00ED7EE3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 5B7C6E5F2CDB6A560024704A /* Build configuration list for PBXProject "NearbyNetwork" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkBrowser.swift b/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkBrowser.swift index 3bee36b..231acbb 100644 --- a/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkBrowser.swift +++ b/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkBrowser.swift @@ -9,11 +9,19 @@ import Foundation import Network import OSLog -final class NearbyNetworkBrowser { +public protocol NearbyNetworkBrowserDelegate: AnyObject { + func nearbyNetworkBrowserDidFindPeer( + _ sender: NearbyNetworkBrowser, + hostName: String, + connectedPeerInfo: [String]) +} + +public final class NearbyNetworkBrowser { let nwBrowser: NWBrowser private let browserQueue: DispatchQueue private let serviceType: String private let logger: Logger + weak var delegate: NearbyNetworkBrowserDelegate? init(serviceType: String) { nwBrowser = NWBrowser( @@ -33,8 +41,21 @@ final class NearbyNetworkBrowser { for result in results { switch result.metadata { case .bonjour(let foundedPeerData): - // TODO: - 추후 발견한 데이터 이용 - print("") + let dictionary = foundedPeerData.dictionary + guard + let hostName = dictionary[NearbyNetworkKey.host.rawValue], + let connectedPeerInfo = dictionary[NearbyNetworkKey.connectedPeerInfo.rawValue] + else { + logger.log(level: .error, "connection의 데이터 값이 유효하지 않습니다.") + return + } + + delegate?.nearbyNetworkBrowserDidFindPeer( + self, + hostName: hostName, + connectedPeerInfo: connectedPeerInfo + .split(separator: ",") + .map { String($0) }) default: logger.log(level: .error, "알 수 없는 피어가 발견되었습니다.") } diff --git a/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkKey.swift b/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkKey.swift index 08a5dc3..0a0e9e5 100644 --- a/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkKey.swift +++ b/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkKey.swift @@ -5,7 +5,7 @@ // Created by 최정인 on 12/31/24. // -enum NearbyNetworkKey: String { +public enum NearbyNetworkKey: String { case host case connectedPeerInfo } diff --git a/NearbyNetwork/NearbyNetwork/Sources/RefactoredNearbyNetworkService.swift b/NearbyNetwork/NearbyNetwork/Sources/RefactoredNearbyNetworkService.swift index 5f1f70e..a479f45 100644 --- a/NearbyNetwork/NearbyNetwork/Sources/RefactoredNearbyNetworkService.swift +++ b/NearbyNetwork/NearbyNetwork/Sources/RefactoredNearbyNetworkService.swift @@ -12,16 +12,17 @@ import Network import OSLog // TODO: - 추후 기능 동작 확인 후 NearbyNetworkService 대체 -final class RefactoredNearbyNetworkService { - var connectionDelegate: NearbyNetworkConnectionDelegate? = nil +public final class RefactoredNearbyNetworkService { + public var connectionDelegate: NearbyNetworkConnectionDelegate? = nil private let serviceName: String private let serviceType: String private let peerID: UUID private let nearbyNetworkListener: NearbyNetworkListener private let nearbyNetworkBrowser: NearbyNetworkBrowser private let logger: Logger + public var foundPeerHandler: ((_ hostName: String, _ connectedPeerInfo: [String]) -> Void)? - public init(serviceName: String, serviceType: String) throws { + public init(serviceName: String, serviceType: String) { peerID = UUID() logger = Logger() nearbyNetworkListener = NearbyNetworkListener( @@ -30,15 +31,17 @@ final class RefactoredNearbyNetworkService { nearbyNetworkBrowser = NearbyNetworkBrowser(serviceType: serviceType) self.serviceName = serviceName self.serviceType = serviceType + nearbyNetworkBrowser.delegate = self } } +// MARK: - NearbyNetworkInterface 메서드 구현 extension RefactoredNearbyNetworkService: NearbyNetworkInterface { - var reciptDataPublisher: AnyPublisher { + public var reciptDataPublisher: AnyPublisher { return Just(Data()).eraseToAnyPublisher() } - var reciptURLPublisher: AnyPublisher<(url: URL, dataInfo: DataInformationDTO), Never> { + public var reciptURLPublisher: AnyPublisher<(url: URL, dataInfo: DataInformationDTO), Never> { // TODO: - will be deprecated guard let url = URL(string: "https://naver.com") else { fatalError() } let dataInfo = DataInformationDTO( @@ -49,45 +52,57 @@ extension RefactoredNearbyNetworkService: NearbyNetworkInterface { .eraseToAnyPublisher() } - func startSearching() { + public func startSearching() { nearbyNetworkBrowser.startSearching() } - func stopSearching() { + public func stopSearching() { nearbyNetworkBrowser.stopSearching() } - func startPublishing(with info: [String: String]) { + public func startPublishing(with info: [String: String]) { // TODO: - will be deprecated } - func startPublishing(with hostName: String, connectedPeerInfo: [String]) { + public func startPublishing(with hostName: String, connectedPeerInfo: [String]) { nearbyNetworkListener.startPublishing( hostName: hostName, connectedPeerInfo: connectedPeerInfo) } - func stopPublishing() { + public func stopPublishing() { nearbyNetworkListener.stopPublishing() } - func disconnectAll() { + public func disconnectAll() { } - func joinConnection(connection: NetworkConnection, context: RequestedContext) throws { + public func joinConnection(connection: NetworkConnection, context: RequestedContext) throws { } - func send(data: Data) { + public func send(data: Data) { } - func send(fileURL: URL, info: DataInformationDTO) async { + public func send(fileURL: URL, info: DataInformationDTO) async { // TODO: - will be deprecated } - func send(fileURL: URL, info: DataInformationDTO, to connection: NetworkConnection) async { + public func send(fileURL: URL, info: DataInformationDTO, to connection: NetworkConnection) async { // TODO: - will be deprecated } } + +// MARK: - NearbyNetworkBrowserDelegate +extension RefactoredNearbyNetworkService: NearbyNetworkBrowserDelegate { + public func nearbyNetworkBrowserDidFindPeer( + _ sender: NearbyNetworkBrowser, + hostName: String, + connectedPeerInfo: [String] + ) { + guard let foundPeerHandler else { return } + foundPeerHandler(hostName, connectedPeerInfo) + } +} diff --git a/NearbyNetwork/NearbyNetworkTests/NearbyNetworkTests.swift b/NearbyNetwork/NearbyNetworkTests/NearbyNetworkTests.swift new file mode 100644 index 0000000..31d5b1e --- /dev/null +++ b/NearbyNetwork/NearbyNetworkTests/NearbyNetworkTests.swift @@ -0,0 +1,118 @@ +// +// NearbyNetworkTests.swift +// NearbyNetworkTests +// +// Created by 이동현 on 12/31/24. +// + +import NearbyNetwork +import Network +import XCTest + +final class NearbyNetworkTests: XCTestCase { + var nearbyNetworkService: RefactoredNearbyNetworkService? + + override func setUpWithError() throws { + nearbyNetworkService = RefactoredNearbyNetworkService( + serviceName: "airplain", + serviceType: "_airplain._tcp") + } + + override func tearDownWithError() throws { + nearbyNetworkService = nil + } + + func testAdvertisingSuccess() { + // 준비 + let expectedHostName = "host" + let expectedConnectedPeerInfo = ["1", "2", "3"] + let serviceType = "_airplain._tcp" + let browserQueue = DispatchQueue.global() + let browser = NWBrowser( + for: .bonjourWithTXTRecord(type: serviceType, domain: nil), + using: .tcp) + let browsingExpectation = XCTestExpectation(description: "검색 성공 여부") + var browsedHostName: String? + var browsedPeerInfo: String? + + // 실행 + XCTAssertNotNil(nearbyNetworkService) + nearbyNetworkService?.startPublishing( + with: expectedHostName, + connectedPeerInfo: expectedConnectedPeerInfo) + + browser.start(queue: browserQueue) + browser.browseResultsChangedHandler = { results, _ in + for result in results { + switch result.metadata { + case .bonjour(let foundedPeerData): + browsedHostName = foundedPeerData.dictionary[NearbyNetworkKey.host.rawValue] + browsedPeerInfo = foundedPeerData.dictionary[NearbyNetworkKey.connectedPeerInfo.rawValue] + browsingExpectation.fulfill() + default: + break + } + break + } + } + wait(for: [browsingExpectation], timeout: 3) + + // 검증 + guard + let browsedHostName, + let browsedPeerInfo + else { + XCTFail("browsedHostName, browsedPeerInfo가 정상적으로 초기화되지 않았습니다.") + return + } + + XCTAssertEqual(expectedHostName, browsedHostName) + XCTAssertEqual(expectedConnectedPeerInfo.joined(separator: ","), browsedPeerInfo) + } + + func testBrowsingSuccess() { + // 준비 + let expectedHostName = "host" + let expectedConnectedPeerInfo = ["1", "2", "3"] + let txtRecord = NWTXTRecord([ + NearbyNetworkKey.host.rawValue: expectedHostName, + NearbyNetworkKey.connectedPeerInfo.rawValue: expectedConnectedPeerInfo.joined(separator: ",") + ]) + guard let advertiser = try? NWListener(using: .tcp) else { + XCTFail("advertiser 생성 실패") + return + } + let advertiserQueue = DispatchQueue.global() + let advertisingExpectation = XCTestExpectation(description: "광고 성공 여부") + var advertisingHostName: String? + var advertisingPeerInfo: [String]? + let foundPeerHandler: (String, [String]) -> Void = { hostName, connectedPeerInfo in + advertisingHostName = hostName + advertisingPeerInfo = connectedPeerInfo + advertisingExpectation.fulfill() + } + nearbyNetworkService?.foundPeerHandler = foundPeerHandler + advertiser.newConnectionHandler = { _ in } + advertiser.service = NWListener.Service( + name: "airplain", + type: "_airplain._tcp", + txtRecord: txtRecord) + + // 실행 + advertiser.start(queue: advertiserQueue) + nearbyNetworkService?.startSearching() + wait(for: [advertisingExpectation], timeout: 3) + + // 검증 + guard + let advertisingHostName, + let advertisingPeerInfo + else { + XCTFail("advertisingHostName, advertisingPeerInfo가 정상적으로 초기화되지 않았습니다.") + return + } + + XCTAssertEqual(expectedHostName, advertisingHostName) + XCTAssertEqual(expectedConnectedPeerInfo, advertisingPeerInfo) + } +} From 6962f0d80eb7f0672354ee77accfa8e8c4c9dc84 Mon Sep 17 00:00:00 2001 From: taipaise Date: Thu, 2 Jan 2025 15:29:25 +0900 Subject: [PATCH 7/7] =?UTF-8?q?refactor:=20=EC=BD=94=EB=93=9C=20=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xcschemes/NearbyNetwork.xcscheme | 80 +++++++++++++++++++ .../xcschemes/NearbyNetworkTests.xcscheme | 65 +++++++++++++++ .../Sources/NearbyNetworkBrowser.swift | 2 +- .../Sources/NearbyNetworkListener.swift | 2 +- .../NearbyNetworkTests.swift | 39 +++++---- 5 files changed, 172 insertions(+), 16 deletions(-) create mode 100644 NearbyNetwork/NearbyNetwork.xcodeproj/xcshareddata/xcschemes/NearbyNetwork.xcscheme create mode 100644 NearbyNetwork/NearbyNetwork.xcodeproj/xcshareddata/xcschemes/NearbyNetworkTests.xcscheme diff --git a/NearbyNetwork/NearbyNetwork.xcodeproj/xcshareddata/xcschemes/NearbyNetwork.xcscheme b/NearbyNetwork/NearbyNetwork.xcodeproj/xcshareddata/xcschemes/NearbyNetwork.xcscheme new file mode 100644 index 0000000..88804ce --- /dev/null +++ b/NearbyNetwork/NearbyNetwork.xcodeproj/xcshareddata/xcschemes/NearbyNetwork.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NearbyNetwork/NearbyNetwork.xcodeproj/xcshareddata/xcschemes/NearbyNetworkTests.xcscheme b/NearbyNetwork/NearbyNetwork.xcodeproj/xcshareddata/xcschemes/NearbyNetworkTests.xcscheme new file mode 100644 index 0000000..5f3eea3 --- /dev/null +++ b/NearbyNetwork/NearbyNetwork.xcodeproj/xcshareddata/xcschemes/NearbyNetworkTests.xcscheme @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkBrowser.swift b/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkBrowser.swift index 231acbb..e862121 100644 --- a/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkBrowser.swift +++ b/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkBrowser.swift @@ -17,7 +17,7 @@ public protocol NearbyNetworkBrowserDelegate: AnyObject { } public final class NearbyNetworkBrowser { - let nwBrowser: NWBrowser + private let nwBrowser: NWBrowser private let browserQueue: DispatchQueue private let serviceType: String private let logger: Logger diff --git a/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkListener.swift b/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkListener.swift index 0b47019..8fa3e2a 100644 --- a/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkListener.swift +++ b/NearbyNetwork/NearbyNetwork/Sources/NearbyNetworkListener.swift @@ -10,7 +10,7 @@ import Network import OSLog final class NearbyNetworkListener { - var nwListener: NWListener? + private var nwListener: NWListener? private let listenerQueue: DispatchQueue private let serviceName: String private let serviceType: String diff --git a/NearbyNetwork/NearbyNetworkTests/NearbyNetworkTests.swift b/NearbyNetwork/NearbyNetworkTests/NearbyNetworkTests.swift index 31d5b1e..a14f614 100644 --- a/NearbyNetwork/NearbyNetworkTests/NearbyNetworkTests.swift +++ b/NearbyNetwork/NearbyNetworkTests/NearbyNetworkTests.swift @@ -11,11 +11,22 @@ import XCTest final class NearbyNetworkTests: XCTestCase { var nearbyNetworkService: RefactoredNearbyNetworkService? + var mockBrowser: NWBrowser? + var mockListener: NWListener? + let serviceName = "airplain" + let serviceType = "_airplain._tcp" override func setUpWithError() throws { nearbyNetworkService = RefactoredNearbyNetworkService( - serviceName: "airplain", - serviceType: "_airplain._tcp") + serviceName: serviceName, + serviceType: serviceType) + + mockBrowser = NWBrowser( + for: .bonjourWithTXTRecord(type: serviceType, domain: nil), + using: .tcp) + + mockListener = try? NWListener(using: .tcp) + mockListener?.newConnectionHandler = { _ in } } override func tearDownWithError() throws { @@ -26,14 +37,14 @@ final class NearbyNetworkTests: XCTestCase { // 준비 let expectedHostName = "host" let expectedConnectedPeerInfo = ["1", "2", "3"] - let serviceType = "_airplain._tcp" let browserQueue = DispatchQueue.global() - let browser = NWBrowser( - for: .bonjourWithTXTRecord(type: serviceType, domain: nil), - using: .tcp) let browsingExpectation = XCTestExpectation(description: "검색 성공 여부") var browsedHostName: String? var browsedPeerInfo: String? + guard let mockBrowser else { + XCTFail("mockBrowser가 초기화되지 않았습니다.") + return + } // 실행 XCTAssertNotNil(nearbyNetworkService) @@ -41,8 +52,8 @@ final class NearbyNetworkTests: XCTestCase { with: expectedHostName, connectedPeerInfo: expectedConnectedPeerInfo) - browser.start(queue: browserQueue) - browser.browseResultsChangedHandler = { results, _ in + mockBrowser.start(queue: browserQueue) + mockBrowser.browseResultsChangedHandler = { results, _ in for result in results { switch result.metadata { case .bonjour(let foundedPeerData): @@ -78,7 +89,8 @@ final class NearbyNetworkTests: XCTestCase { NearbyNetworkKey.host.rawValue: expectedHostName, NearbyNetworkKey.connectedPeerInfo.rawValue: expectedConnectedPeerInfo.joined(separator: ",") ]) - guard let advertiser = try? NWListener(using: .tcp) else { + + guard let mockListener else { XCTFail("advertiser 생성 실패") return } @@ -92,14 +104,13 @@ final class NearbyNetworkTests: XCTestCase { advertisingExpectation.fulfill() } nearbyNetworkService?.foundPeerHandler = foundPeerHandler - advertiser.newConnectionHandler = { _ in } - advertiser.service = NWListener.Service( - name: "airplain", - type: "_airplain._tcp", + mockListener.service = NWListener.Service( + name: serviceName, + type: serviceType, txtRecord: txtRecord) // 실행 - advertiser.start(queue: advertiserQueue) + mockListener.start(queue: advertiserQueue) nearbyNetworkService?.startSearching() wait(for: [advertisingExpectation], timeout: 3)