Network Framework peer-to-peer + Bluetooth Proximity

Hello there,
I'm currently working on the networking side of my SwiftUI app, and my question is, how would I go about making both devices both NWBrowsers and NWListeners at the same time? The first device to find an NWListener (through Bluetooth proximity and NWBrowser) would tell the other to cancel their NWBrowser, effectively becoming the server while the first one stays the client. Then, when the data transfer from the server to the client is done, they would switch places, so that the first phone can transfer their data to the second.

I don't have much experience in Networking, and the lack of explanative documentation for the Network Framework means the learning curve is very steep. Do I even need to do the server-client switching, or will NWConnection take care of that? Maybe a custom framing protocol, like what Apple showed in their WWDC presentation? I would be grateful for a few pointers or what direction I should take.

P.S: I know MultipeerConnectivity fits my needs and abstracts away many of the technicalities in networking, but it's unsupported (compared to Network) and doesn't offer the level of customisation that I'll need in the future (especially for Bluetooth proximity, which is how, when an NWListener gets very close, NWBrowser knows it must connect to it).
Answered by DTS Engineer in 640133022
SwiftUI is irrelevant to this discussion. You’d have the same problems if you were using any other UI framework.

As to how you achieve your goal, there’s two complexities here:
  • You’ll want to use TCP and TCP APIs generally work in terms of byte streams. You’ll need a mechanism to send messages over that TCP byte stream. My preferred option here is to use the WebSocket support we added to Network framework in iOS 13.

  • The server/client switching approach you’d like is simply not supported at the TCP level, so you’ll have to implement this yourself. There isn’t a standard way of doing this but it’s not too hard. A good strategy is something like this:


  1. Have each peer decide on its own unique ID.

  2. When a client connects to a server, the first message it sends across that connection contains its unique ID.

  3. The server then responds with its own unique ID.

  4. If either end discovers that a connection with that unique ID pair already exists, it drops one of the connections. As long as they both agree to drop the same connection, everything will be fine. A good strategy here is to drop the one with the lesser ID.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Accepted Answer
SwiftUI is irrelevant to this discussion. You’d have the same problems if you were using any other UI framework.

As to how you achieve your goal, there’s two complexities here:
  • You’ll want to use TCP and TCP APIs generally work in terms of byte streams. You’ll need a mechanism to send messages over that TCP byte stream. My preferred option here is to use the WebSocket support we added to Network framework in iOS 13.

  • The server/client switching approach you’d like is simply not supported at the TCP level, so you’ll have to implement this yourself. There isn’t a standard way of doing this but it’s not too hard. A good strategy is something like this:


  1. Have each peer decide on its own unique ID.

  2. When a client connects to a server, the first message it sends across that connection contains its unique ID.

  3. The server then responds with its own unique ID.

  4. If either end discovers that a connection with that unique ID pair already exists, it drops one of the connections. As long as they both agree to drop the same connection, everything will be fine. A good strategy here is to drop the one with the lesser ID.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Thanks a lot! NWProtocolWebSocket seems perfect for the transmission of data. From what I understood, I can:
  1. Have the device create their unique ID (UUID?)

  2. Make the device be a browser and listener (while emitting a Bluetooth signal) simultaneously.

  3. If the device's browser detects a listener (who's BLE signal RSSI passes a certain threshold, meaning the device is right next to/on top of the first), they cancel their own listener and send their unique ID.

  4. Conversely, if the device's listener is connected to by another device's browser, the first device cancels their browser, and once they have received the other end's unique ID, they send their own unique ID.

  5. The device makes a sanity check using your clever method by making sure that this unique ID pair doesn't already exist (which would otherwise mean that this connection has already been made by their opposite browsers and listeners during steps 2-4). If this pair already does exist, the new connection is cancelled.

  6. Once the sanity check is passed, a WebSocket connection is made, and the data is transferred wirelessly between the two phones.






@theepicapple hi, was you able to get around this issue? I'm currently in the same situation
Network Framework peer-to-peer + Bluetooth Proximity
 
 
Q