@@ -163,31 +163,46 @@ public final class MultipeerTransceiver {
163163 public func invite( _ peer: Peer , with context: Data ? , timeout: TimeInterval , completion: InvitationCompletionHandler ? ) {
164164 connection. invite ( peer, with: context, timeout: timeout, completion: completion)
165165 }
166+
167+ public enum PeerEvent : Hashable {
168+ case found( Peer )
169+ case lost( Peer )
170+ case connected( Peer )
171+ case disconnected( Peer )
172+ }
166173
167174 private func handlePeerAdded( _ peer: Peer ) {
168175 guard !availablePeers. contains ( peer) else { return }
169176
170177 availablePeers. append ( peer)
171178 peerAdded ( peer)
179+
180+ peerEventOccurred ( . found( peer) )
172181 }
173182
174183 private func handlePeerRemoved( _ peer: Peer ) {
175184 guard let idx = availablePeers. firstIndex ( where: { $0. underlyingPeer == peer. underlyingPeer } ) else { return }
176185
177186 availablePeers. remove ( at: idx)
178187 peerRemoved ( peer)
188+
189+ peerEventOccurred ( . lost( peer) )
179190 }
180191
181192 private func handlePeerConnected( _ peer: Peer ) {
182193 setConnected ( true , on: peer)
183194
184195 peerConnected ( peer)
196+
197+ peerEventOccurred ( . connected( peer) )
185198 }
186199
187200 private func handlePeerDisconnected( _ peer: Peer ) {
188201 setConnected ( false , on: peer)
189202
190203 peerDisconnected ( peer)
204+
205+ peerEventOccurred ( . disconnected( peer) )
191206 }
192207
193208 private func setConnected( _ connected: Bool , on peer: Peer ) {
@@ -197,5 +212,44 @@ public final class MultipeerTransceiver {
197212 mutablePeer. isConnected = connected
198213 availablePeers [ idx] = mutablePeer
199214 }
215+
216+ // MARK: - Swift Concurrency Support
217+
218+ private typealias PeerEventCallback = ( PeerEvent ) -> Void
219+
220+ private var internalPeerEventCallbacks : [ UUID : PeerEventCallback ] = [ : ]
221+
222+ private func addInternalPeerEventsCallback( with block: @escaping PeerEventCallback ) -> UUID {
223+ let id = UUID ( )
224+ internalPeerEventCallbacks [ id] = block
225+ return id
226+ }
227+
228+ private func peerEventOccurred( _ event: PeerEvent ) {
229+ DispatchQueue . main. async {
230+ self . internalPeerEventCallbacks. values. forEach { $0 ( event) }
231+ }
232+ }
200233
201234}
235+
236+ @available ( tvOS 13 . 0 , * )
237+ @available ( iOS 13 . 0 , * )
238+ @available ( macOS 10 . 15 , * )
239+ public extension MultipeerTransceiver {
240+
241+ var peerEvents : AsyncStream < PeerEvent > {
242+ AsyncStream { [ weak self] continuation in
243+ guard let self = self else { return }
244+
245+ let id = self . addInternalPeerEventsCallback { event in
246+ continuation. yield ( event)
247+ }
248+
249+ continuation. onTermination = { @Sendable _ in
250+ self . internalPeerEventCallbacks [ id] = nil
251+ }
252+ }
253+ }
254+
255+ }
0 commit comments