Search code examples
iosswiftudpbroadcast

iOS app not receiving UDP broadcast datagrams


I am fairly new to iOS and I am trying to make my app listen to all UDP broadcasts on a port (10704). I already have this implemented on Android version (sending and receiving) so I am 100% sure, that network requests are being sent. I get output, that setup happened, but nothing else. I never get any sign of incoming network data on iOS side. My code so far (class in created in didFinishLaunchingWithOptions of Application class:

import CocoaAsyncSocket

class InSocket: NSObject, GCDAsyncUdpSocketDelegate {


   let PORT:UInt16 = 10704
   var socket:GCDAsyncUdpSocket!

   override init(){
       super.init()
       setupConnection()
   }

   func setupConnection(){
        socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: DispatchQueue.global())
        try! socket.bind(toPort: PORT)
        try! socket.enableBroadcast(true)
        try! socket.beginReceiving()
        print("after setup!")
   }
    
    func udpSocket(_ sock: GCDAsyncUdpSocket, didNotConnect error: Error?) {
        print("didNotConnect!")
    }
    
    func udpSocket(_ sock: GCDAsyncUdpSocket, didSendDataWithTag tag: Int) {
        print("didSendDataWithTag")
    }
    
    func udpSocket(_ sock: GCDAsyncUdpSocket, didConnectToAddress address: Data) {
        print("didConnectToAddress")
    }
    
    func udpSocket(_ sock: GCDAsyncUdpSocket, didNotSendDataWithTag tag: Int, dueToError error: Error?) {
        print("didNotSendDataWithTag")
    }
    
    func udpSocketDidClose(_ sock: GCDAsyncUdpSocket, withError error: Error?) {
        print("udpSocketDidClose")
    }

    func udpSocket(_ sock: GCDAsyncUdpSocket, didReceive data: Data, fromAddress address: Data, withFilterContext filterContext: Any?) {
        print("incoming message1: \(String(describing: data))");
        
    }
    
    func udpSocket(sock: GCDAsyncUdpSocket!, didReceiveData data: NSData!, fromAddress address: NSData!,      withFilterContext filterContext: AnyObject!) {
        print("incoming message2: \(String(describing: data))");
    }
    
}

Last 2 are similar, because 1 of them is copied from sample code (probably outdated signature) and other one is generated by xcode autocomplete.

Edit: added how I create InSocket

    var sckt: InSocket!

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        sckt = InSocket()        
        return true
    }

Solution

  • Not all queues are associated with a RunLoop. Without being associated with a RunLoop a queue can not execute asynchronous work.

    If you move your delegate queue to the main queue, you will receive delegate call backs since the main queue is scheduled onto the main run loop.