Using NEVPNManager to detect VPN status and consistently returning NEVPNStatusInvalid

Hello! My app wants to disable VPN connection. I used the loadFromPreferencesWithCompletionHandler method of NEVPNManager for detection, but regardless of whether the VPN was actually connected or not, it kept returning NEVPNStatusInvalid. How should I handle this issue?

NEVPNManager *vpnManager = [NEVPNManager sharedManager];
    [vpnManager loadFromPreferencesWithCompletionHandler:^(NSError * _Nullable error) {
        if (error) {
            return;
        }

        NEVPNStatus status = vpnManager.connection.status;
        
        switch (status) {
            case NEVPNStatusInvalid:
                // kept returning NEVPNStatusInvalid
                break;
            case NEVPNStatusDisconnected:
                break;
            case NEVPNStatusConnecting:
                break;
            case NEVPNStatusConnected:
                break;
            case NEVPNStatusReasserting:
                break;
            case NEVPNStatusDisconnecting:
                break;
            default:
                break;
        }
    }];
Answered by DTS Engineer in 842119022

OK. The API you’re using only works for VPN configurations associated with your app. Those include:

  • Any configuration you create using Personal VPN

  • If your app has an NE VPN provider:

    • Any VPN configuration you create for that provider
    • Any VPN configuration in a configuration profile that targets your provider

You can’t check the status of other VPN configurations this way. The API just isn’t built to support that case.

instead needs to disable the use of VPN.

Disable the VPN? Or detect a VPN so that you can disable some functionality within your app when one is enabled? Those have slightly different answers.

If you’re asking how to disable VPN then the answer is quite straightforward: An iOS app can only change the state of VPN configurations that are associated with that app (per the list above). You can’t modify another app’s VPN configurations, or configurations created by the user, or configurations from a configuration profile unless they target your NE VPN provider.

As to how you detect the presence of VPN, that’s also tricky. There are various heuristics you can use, but there’s no single API that returns a direct answer. In fact, even coming up with a valid question is tricky. For example, do you consider iCloud Private Relay to be VPN? What about some other form of network relay [1].

Share and Enjoy

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

[1] For more on that, see WWDC 2023 Session 10002 Ready, set, relay: Protect app traffic with network relays.

Is your app using Personal VPN? Or do you have your own packet tunnel provider?

Share and Enjoy

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

Thank you for your reply! My program does not require the use of any VPN, but instead needs to disable the use of VPN. I have added the Personal VPN option to the project's capabilities.

Accepted Answer

OK. The API you’re using only works for VPN configurations associated with your app. Those include:

  • Any configuration you create using Personal VPN

  • If your app has an NE VPN provider:

    • Any VPN configuration you create for that provider
    • Any VPN configuration in a configuration profile that targets your provider

You can’t check the status of other VPN configurations this way. The API just isn’t built to support that case.

instead needs to disable the use of VPN.

Disable the VPN? Or detect a VPN so that you can disable some functionality within your app when one is enabled? Those have slightly different answers.

If you’re asking how to disable VPN then the answer is quite straightforward: An iOS app can only change the state of VPN configurations that are associated with that app (per the list above). You can’t modify another app’s VPN configurations, or configurations created by the user, or configurations from a configuration profile unless they target your NE VPN provider.

As to how you detect the presence of VPN, that’s also tricky. There are various heuristics you can use, but there’s no single API that returns a direct answer. In fact, even coming up with a valid question is tricky. For example, do you consider iCloud Private Relay to be VPN? What about some other form of network relay [1].

Share and Enjoy

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

[1] For more on that, see WWDC 2023 Session 10002 Ready, set, relay: Protect app traffic with network relays.

Using NEVPNManager to detect VPN status and consistently returning NEVPNStatusInvalid
 
 
Q