Following iOS 14 new policy of blocking access to local network, a com.apple.developer.networking.multicast special entitlement is needed to access the local network, and this access should be confirmed by user during an authorization dialog. Although this new feature is not thoroughly documented, Apple engineers have indicated in forums that this authorization dialog popup is only triggered when the app tries to send traffic, causing an issue for apps reading only the network, as indicated in iOS 14 How to trigger Local Network dialog and check user answer?
Unfortunately, the advice of sending some data to trigger the authorization dialog does not seem to work in our case, as we never got the popup dialog appearing.
Our app usually only receive UDP broadcast (no transmit except in a few cases). We have got the com.apple.developer.networking.multicast entitlement, have added it to our app entitlements, have added the requested NSLocalNetworkUsageDescription in our Info.plist and are signing our app manually using XCode 12.0 with a provisioning profile including this entitlement (manual code signing is needed in this case as indicated in https://developer.apple.com/forums/thread/656773?answerId=628537022). Since then, situation has somewhat improved as the UDP packet reception that was fully blocked before adding the entitlement started to work sometimes, but unfortunately not always (situation seems worse on iOS 14.0.1 than on iOS 14 and on iPhone than on iPad).
Most importantly, we never got the authorization dialog displayed and our app does not appear as authorized in Privacy/Local Network (even when UDP reception works). We suspect this may be the cause for this spurious reception issue. As it seems the authorization dialog is only shown when sending data, we configured our app to send data to the local network to try to trigger the dialog, using all below methods:
- TcpSocket class (using CFStreamCreatePairWithSocketToHost) to connect to 192.168.1.1 on port 80 and send a few bytes (there is a device at this address)
- using GCDAsyncSocket to connect and send a test TCP packet to same address/port
- using GCDAsyncUdpSocket to create a UDP socket, enabling it for broadcast, then joinMulticastGroup 224.0.1.0 and broadcasting a test UDP packet on port 80.
- using GCDAsyncUdpSocket to create a UDP socket, enabling it for broadcast, then broadcasting a test UDP packet on port 80 to 255.255.255.255.
- reusing the example from Apple article (https://developer.apple.com/news/?id=0oi77447) sending multicast packets with NWConnectionGroup to 224.0.1.0
- and finally using the triggerDialog() method of class LocalNetworkPermissionService indicated in iOS 14 How to trigger Local Network dialog and check user answer?
None of the above actions triggered the authorization dialog on iOS 14.0 and iOS 14.0.1, and our app is still not listed as authorized in Privacy/Local Network, with spurious reception of UDP packets.
If somebody has encountered the same issue and found a solution, many thanks for your advice.