Apply for the Multicast Networking capability

To use UDP broadcast in iOS, you must submit a Multicast Networking Entitlement Request application to Apple using the link below:
https://developer.apple.com/contact/request/networking-multicast

Sample information you need to provide

APP Name : XXXXX
App Store URL : https://apps.apple.com/us/app/xxxxxxxxx
Apple ID : 1234567890
App Category : the APP’s category

Describe the main purpose of your app:
The app helps users to setup our company’s router products.

Explain why your app needs to send multicast:
Our APP uses the UDP broadcast to discover our company’s devices.

UDP IP : 255.255.255.255
Port : 12345

Waiting for serval days, if your application is approved by Apple, you will see the Multicast Networking capability in your APP identifier’s Additional Capabilities.

UDP broadcast via CocoaAsyncSocket

My sample project source code in GitHub

Please note: In order to run the sample project, you need to use the iPhone simulator. If you try to run the sample project on a real phone, you will need to have “Multicast Networking capability”.

Pod install

1
pod 'CocoaAsyncSocket'

If you use XCode 13+, set the project format to avoid pod init error

Start broadcast

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func startBroadcast(port:Int, data:Data) -> Bool{
socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: DispatchQueue.main)
guard let s = socket else{
return false
}
s.setIPv6Enabled(false)

do {
try s.bind(toPort: UInt16(port), interface: "en0")
try s.enableBroadcast(true)
try s.beginReceiving()
} catch {
print("Error: \(error)")
return false
}

s.send(data, toHost: "255.255.255.255", port: UInt16(port), withTimeout: -1, tag: 0)
return true
}

Stop broadcast

1
2
3
4
func stopBroadcast(){
socket?.close()
socket = nil
}

Handle delegate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
extension UDPBroadcast: GCDAsyncUdpSocketDelegate{
func udpSocket(_ sock: GCDAsyncUdpSocket, didReceive data: Data, fromAddress address: Data, withFilterContext filterContext: Any?) {
var host: NSString?
var port: UInt16 = 0
GCDAsyncUdpSocket.getHost(&host, port: &port, fromAddress: (address as Data?)!)

let dataStr = data.reduce("") {$0 + String(format: "0x%02x ", $1)}
print("Receive data from \(host ?? "N/A") \(port)")
print(dataStr)
}

func udpSocketDidClose(_ sock: GCDAsyncUdpSocket, withError error: Error?) {
print("socket close with error \(String(describing: error))")
}
}

UDP broadcast via NWConnection

Technically, NWConnection can be used to perform UDP broadcast. However, in my experience, I have not been able to get it to work.