NWConnection with .UDP never gets beyond 'Preparing' state

I'm trying to send data using UDP using the following code, But I never get any 'newState' other than .preparing:

Do I need to set an entitlement or something, or have I missed a point somewhere?


(iOS 13, Xcode 11.7, SwiftUI)

Code Block
var connection: NWConnection?
var hostUDP: NWEndpoint.Host = "239.255.250.78"
var portUDP: NWEndpoint.Port = 4002
func start() {
print("UDP Provider has started")
self.connectToUDP(hostUDP, portUDP)
}
func connectToUDP(_ hostUDP: NWEndpoint.Host, _ portUDP: NWEndpoint.Port) {
    let messageToUDP = "ANNOUNCE"
    connection = NWConnection(host: hostUDP, port: portUDP, using: .udp)
    connection?.stateUpdateHandler = { (newState) in
      switch (newState) {
        case .ready:
          print("State: Ready\n")
          self.sendUDP(messageToUDP)
          self.receiveUDP()
        case .setup:
          print("State: Setup\n")
        case .cancelled:
          print("State: Cancelled\n")
        case .preparing:
          print("State: Preparing\n")
        default:
          print("ERROR! State not defined!\n")
      }
    }
    connection?.start(queue: .global())
  }
  func sendUDP(_ content: String) {
    let contentToSendUDP = content.data(using: String.Encoding.utf8)
    connection?.send(content: contentToSendUDP, completion: NWConnection.SendCompletion.contentProcessed(({ (NWError) in
      if (NWError == nil) {
        print("Data was sent to UDP")
      } else {
        print("ERROR! Error when data (Type: Data) sending. NWError: \n \(NWError!)")
      }
    })))
  }
  func receiveUDP() {
    connection?.receiveMessage { (data, context, isComplete, error) in
      if (isComplete) {
        print("Receive is complete")
        if (data != nil) {
          let backToString = String(decoding: data!, as: UTF8.self)
          print("Received message: \(backToString)")
        } else {
          print("Data == nil")
        }
      }
    }
  }



Answered by DTS Engineer in 632319022
Your hostUDP value is set to 239.255.250.78, which is an IPv4 multicast address. NWConnection does not support multicast. If you’re OK with requiring the upcoming iOS 14, you can use NWConnectionGroup. If you must support older systems, you’ll have to use BSD Sockets.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Stop the build, clean the build folder, restart Xcode and try again, but not until you confirm several tens GB free space, trash emptied, on your SSD.

Good luck.
Accepted Answer
Your hostUDP value is set to 239.255.250.78, which is an IPv4 multicast address. NWConnection does not support multicast. If you’re OK with requiring the upcoming iOS 14, you can use NWConnectionGroup. If you must support older systems, you’ll have to use BSD Sockets.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
@Quinn The Eskimo
Once again I am in your debt!
Yes I need to support multicast addresses and iOS13 as a minimum - so BSD Sockets it is!
Fortunately I alreadu have a load of BSD stuff in the previous version of this app (Obj-C, Cocoa) which I will now try to port oevr to SwiftUI.

Wish me luck as I google how to call C style code from SwitfUI.....

Thanks again!
.ps. I really don't like these new forums.. I guess Apple would prefer us to use Stackexchange.
@KMT
Not helpful.

Wish me luck as I google how to call C style code from SwitfUI.....

SwiftUI shouldn’t come into this, but Swift is an important factor here. Calling BSD Socket from Swift is tricky. If you already have Objective-C code for this, it would be much more sensible to wrap that in a reasonable abstraction layer and call it from your Swift code.

If you’re absolutely committed to doing this in Swift well… sheesh… I have a whole bunch of info on that topic but it’s too big to share here.

I really don't like these new forums.

I’d like to get your feedback about that. If you put it in a new thread and tag it with Forums Feedback, I’ll respond there.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"

but it’s too big to share here.

Oh, wait, we have the fancy new text attachments feature. Attached below is SystemSocketAdditions.swift, the latest evolution in my ‘how to call BSD Sockets from Swift without going insane’ code.



Two things to note here:
  • To get an idea of how my thinking has evolved in this space, compare it to the earlier version that you can find in the Socket API Helper section of the UnsafeRawPointer Migration doc.

  • This builds on the new Swift System framework, because I only needed to use it on iOS 14 beta. To use it on older systems you’ll need to shim out enough of System to make it work. This is relatively straightforward.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
@Quinn

Thanks again - I will look at your attachment and see if I can get my head round it.
I truly wish I could target just iOS 14 - but I'm afraid I can't :-(

You're right - I said SwiftUI, but I meant Swift... having done Objective-C for the past 15+ years, my old brain is finding it hard to migrate to Swift, but one must move with the times! I remember when we used to get Apple Developer tools shipped to us by UPS on CD's! My first apps were home-automation apps using Xcode and IB... now I'm doing some really cool stuff with Film and TV makers on movie sets using loads of UDP... whenever I post one of my silly questions I always hope I'll get an answer from Quinn The Eskimo! Thanks again. :-)
I got this working :-)
But I wimped out :-(

I just lifted my Obj-c code from the previous project, added the bridging header and viola! It just worked.
So I guess that's OK - not 100% sure what the implications are (Is obj-c being deprecated? How long before I just have to figure out how to do all this in Swift?)

I did try to get it working in Swift (Targetting iOS 13) but gave up - the time/gain balance was all wrong for now.

Thanks @Quinn - your help is invaluable!

But I wimped out :-(

That’s not the right way to think about this. Rather:
  • You saved time by reusing existing code.

  • Objective-C will be around for a very long time.

  • If you do decide to switch over to Swift in the future, your deployment target will allow you to use NWConnectionGroup and thus you’ll never need to feel the pain of using BSD Sockets from Swift.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
NWConnection with .UDP never gets beyond 'Preparing' state
 
 
Q