Local Network Connection is still working even after denied the permission when asked

I've a iOT companion app, in which I'll connect to iOT's Wi-Fi and then communicate the device with APIs,

for the above functionality we needed local network permission So we enabled neccessary keys in info.plist and at the time of App Launch we trigger local network permission using the following code

info.plist

	<string>This app needs local network access permission to connect with your iOT device and customize its settings</string>
	<key>NSBonjourServices</key>
	<array>
    <string>_network-perm._tcp</string>
    <string>_network-perm._udp</string>
	</array>

Network Permission Trigger Methods

import Foundation
import MultipeerConnectivity

class NetworkPermissionManager: NSObject {
  static let shared = NetworkPermissionManager()

  private var session: MCSession?
  private var advertiser: MCNearbyServiceAdvertiser?
  private var browser: MCNearbyServiceBrowser?
  private var permissionCallback: ((String) -> Void)?

  func requestPermission(callback: @escaping (String) -> Void) {
    self.permissionCallback = callback

    do {
      let peerId = MCPeerID(displayName: UUID().uuidString)
      session = MCSession(peer: peerId, securityIdentity: nil, encryptionPreference: .required)
      session?.delegate = self

      advertiser = MCNearbyServiceAdvertiser(
        peer: peerId,
        discoveryInfo: nil,
        serviceType: "network-perm"
      )
      advertiser?.delegate = self

      browser = MCNearbyServiceBrowser(
        peer: peerId,
        serviceType: "network-perm"
      )
      browser?.delegate = self

      advertiser?.startAdvertisingPeer()
      browser?.startBrowsingForPeers()

      // Stop after delay
      DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { [weak self] in
        self?.stopAll()
        // If no error occurred until now, consider permission triggered
        self?.permissionCallback?("granted")
        self?.permissionCallback = nil
      }

    } catch {
      permissionCallback?("error: \(error.localizedDescription)")
      permissionCallback = nil
    }
  }

  func stopAll() {
    advertiser?.stopAdvertisingPeer()
    browser?.stopBrowsingForPeers()
    session?.disconnect()
  }
}

extension NetworkPermissionManager: MCSessionDelegate {
  func session(_: MCSession, peer _: MCPeerID, didChange _: MCSessionState) {}
  func session(_: MCSession, didReceive _: Data, fromPeer _: MCPeerID) {}
  func session(_: MCSession, didReceive _: InputStream, withName _: String, fromPeer _: MCPeerID) {}
  func session(_: MCSession, didStartReceivingResourceWithName _: String, fromPeer _: MCPeerID, with _: Progress) {}
  func session(_: MCSession, didFinishReceivingResourceWithName _: String, fromPeer _: MCPeerID, at _: URL?, withError _: Error?) {}
}

extension NetworkPermissionManager: MCNearbyServiceAdvertiserDelegate {
  func advertiser(_: MCNearbyServiceAdvertiser, didReceiveInvitationFromPeer _: MCPeerID, withContext _: Data?, invitationHandler: @escaping (Bool, MCSession?) -> Void) {
    invitationHandler(false, nil)
  }

  func advertiser(_: MCNearbyServiceAdvertiser, didNotStartAdvertisingPeer error: Error) {
    print("❌ Advertising failed: \(error)")

    if let nsError = error as NSError?, nsError.domain ==  NetService.errorDomain, nsError.code == -72008 {
      permissionCallback?("denied")
    } else {
      permissionCallback?("error: \(error.localizedDescription)")
    }

    permissionCallback = nil
    stopAll()
  }
}

extension NetworkPermissionManager: MCNearbyServiceBrowserDelegate {
  func browser(_: MCNearbyServiceBrowser, foundPeer _: MCPeerID, withDiscoveryInfo _: [String: String]?) {}
  func browser(_: MCNearbyServiceBrowser, lostPeer _: MCPeerID) {}

  func browser(_: MCNearbyServiceBrowser, didNotStartBrowsingForPeers error: Error) {
    print("❌ Browsing failed: \(error)")

    if let nsError = error as NSError?, nsError.domain ==  NetService.errorDomain, nsError.code == -72008 {
      permissionCallback?("denied")
    } else {
      permissionCallback?("error: \(error.localizedDescription)")
    }

    permissionCallback = nil
    stopAll()
  }
}```


I want to satisfy this following cases but it's not working as expected

# Case1  Working
App launches --> trigger permission using above code --> user granted permission --> connect to iOT's Wi-Fi using app --> Communicate via Local API ---> should return success response

# Case2  Not working 
App launches --> trigger permission using above code --> user denied permission --> connect to iOT's Wi-Fi using app --> Communicate via Local API ---> should  throw an error

I double checked the permission status in the app settings there also showing disabled state 

In my case case 2 is also return success, even though user denied the permission I got success response. I wonder why this happens

the same above 2 cases working as expected in iOS 17.x versions
Answered by DTS Engineer in 845432022
the same above 2 cases working as expected in iOS 17.x versions

So where is it failing?

If things are behaving on iOS 17 and acting weirdly on iOS 18, I recommend that you retest on the latest iOS 18.6 beta (22G5054d). It contains a fix for a local network privacy bug that can cause all sorts of weird behaviour (r. 131764908).

Share and Enjoy

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

the same above 2 cases working as expected in iOS 17.x versions

So where is it failing?

If things are behaving on iOS 17 and acting weirdly on iOS 18, I recommend that you retest on the latest iOS 18.6 beta (22G5054d). It contains a fix for a local network privacy bug that can cause all sorts of weird behaviour (r. 131764908).

Share and Enjoy

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

Accepted Answer

We have tested on iOS 18.6 beta as well, and the behavior remains the same the Local Network Permission is not functioning correctly.

As I understand it, once the user grants this permission, it should apply to the entire app, allowing communication with all available local networks, not just a specific network.

But, even when the permission is denied, our flow still works on iOS 18.x, which is unexpected and inconsistent.

On the other hand, in iOS 17.x, if a user accidentally denies the permission when prompted, and we somehow manage to guide them to the app settings to manually enable the permission, the change does not take effect immediately. The user must restart the iPhone or iPad for the changes to reflect in the app, which results in a poor user experience.

Please refer to the attached image for a full comparison of the incorrect flows caused by this inconsistent permission behavior.

I kindly request you to consider this a bug and provide a straightforward solution to address this issue. Thank you.

It looks like you create a new thread about this, so let’s focus our discussions there.

Share and Enjoy

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

I am experiencing the same issue on iOS 26 as well, including iOS 26.5.2.

Even when the user selects Don’t Allow for Local Network access, and the permission remains disabled under the app’s Settings, the app can still communicate successfully with a device on the local network using its local IP address.

Our flow is similar:

  1. The app requests Local Network permission.
  2. The user denies the permission.
  3. The iPhone connects to the IoT device’s Wi-Fi hotspot.
  4. The app sends API requests directly to the device’s local IP address.
  5. The requests still succeed.

Based on the expected Local Network privacy behaviour, the requests should fail when permission is denied. However, the permission currently does not appear to prevent direct local network communication.

This suggests that the issue reported for iOS 18 may still be present in iOS 26.

This suggests that the issue reported for iOS 18 may still be present in iOS 26.

Hmmmm, no. When we investigated veerasivaraman’s primary issue, FB18502752, we determined that the local network privacy prompt wasn’t showing because the address they’re accessing wasn’t on a local network.

Which is representative of my general experience with local network privacy on modern versions of iOS. It seems to work pretty much as explained in TN3179 Understanding local network privacy.

IMPORTANT This isn’t to say that I think local network privacy works perfectly. We continue to find problems with it, especially on macOS. However, the majority of problem reports I see from iOS are misunderstandings of how it actually works.

Regarding step 3, does your accessory contain a DHCP server? If so, does its DHCP response list the accessory’s IP address as a DNS server. If so, local network privacy doesn’t apply. Quoting TN3179:

Note these exceptions to the rules above:

  • If your device’s DNS server is on a local network, traffic to it doesn’t require local network access.

Share and Enjoy

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

Local Network Connection is still working even after denied the permission when asked
 
 
Q