Check whether device is connected to a VPN in iOS 12
Asked Answered
Z

3

5

I am using the code below (Swift 3 and Swift 4 compatible) to check the VPN connection on iOS devices which is not working in iOS 12 and above. How can I check the vpn connectivity in iOS 12

func isVPNConnected() -> Bool {
    let cfDict = CFNetworkCopySystemProxySettings()
    let nsDict = cfDict!.takeRetainedValue() as NSDictionary
    let keys = nsDict["__SCOPED__"] as! NSDictionary

    for key: String in keys.allKeys as! [String] {
        if (key == "tap" || key == "tun" || key == "ppp" || key == "ipsec" || key == "ipsec0") {
            return true
        }
    }
    return false
}

Thank you for your help.

Zoa answered 15/11, 2018 at 11:56 Comment(6)
what was the issue u faced , I mean are you validate the key is not available in the substringMohandis
My issue is I need to check whether the device is connected to vpn or. not. The above code works fine in iOS 11 but always returning false in iOS 12. How can I check the vpn connectivity in latest iOS?Zoa
are you validated what the key returns in [string]Mohandis
yes, Getting “en0” alwaysZoa
I think r u tried in the same IP addressMohandis
I didn't get you. if the device is connected to vpn then the IP address will be changed right?Zoa
B
2

Trying adding the key 'utun1' to your check (or prefixed with 'utun' followed by a number).

for key: String in keys.allKeys as! [String] {
    if (key == "tap" || key == "tun" || key == "ppp" || key == "ipsec" || key == "ipsec0" || key == "utun1") {
        return true
    }
}
return false
Beeck answered 15/11, 2018 at 13:27 Comment(0)
H
4

The list of keys has been changed since iOS 12 and iOS 13

2 keys have been added

utun1 and utun2

so the function should be:

static func isConnectedToVPN() -> Bool {

    let cfDict = CFNetworkCopySystemProxySettings()
    let nsDict = cfDict!.takeRetainedValue() as NSDictionary
    let keys = nsDict["__SCOPED__"] as! NSDictionary
    for key: String in keys.allKeys as! [String] {
           if (key == "tap" || key == "tun" || key == "ppp" || key == "ipsec" || key == "ipsec0" || key == "utun1" || key == "utun2") {
               return true
           }
       }
       return false
}
Hassle answered 22/1, 2020 at 13:1 Comment(0)
R
4

In my case, I was receiving an ipsec4 and the app wasn't recognizing the VPN. Therefore I came up with something a bit different:

struct VpnChecker {

    private static let vpnProtocolsKeysIdentifiers = [
        "tap", "tun", "ppp", "ipsec", "utun"
    ]

    static func isVpnActive() -> Bool {
        guard let cfDict = CFNetworkCopySystemProxySettings() else { return false }
        let nsDict = cfDict.takeRetainedValue() as NSDictionary
        guard let keys = nsDict["__SCOPED__"] as? NSDictionary,
            let allKeys = keys.allKeys as? [String] else { return false }

        // Checking for tunneling protocols in the keys
        for key in allKeys {
            for protocolId in vpnProtocolsKeysIdentifiers
                where key.starts(with: protocolId) {
                // I use start(with:), so I can cover also `ipsec4`, `ppp0`, `utun0` etc...
                return true
            }
        }
        return false
    }
}

Usage: VpnChecker.isVpnActive()

I also wrote a little blog post about it here

Roundlet answered 15/4, 2020 at 14:31 Comment(1)
It's not working in ios 14.5..any help ?Irregularity
B
2

Trying adding the key 'utun1' to your check (or prefixed with 'utun' followed by a number).

for key: String in keys.allKeys as! [String] {
    if (key == "tap" || key == "tun" || key == "ppp" || key == "ipsec" || key == "ipsec0" || key == "utun1") {
        return true
    }
}
return false
Beeck answered 15/11, 2018 at 13:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.