检查设备是否连接到VPN

时间:2016-01-14 16:08:24

标签: ios swift

我可以使用以下方法检查设备是否已连接到互联网:

var connected: Bool = true
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
let defaultRouteReachability = withUnsafePointer(&zeroAddress) {
    SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0))
}
var flags = SCNetworkReachabilityFlags()
if !SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) {
    connected = false
}
let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
let needsConnection = (flags.rawValue & UInt2(kSCNetworkFlagsConnectionRequired)) != 0

if isReachable && !needsConnection && connected {
    login(usernameTextField.text!, password: appPassword.text!, environment: environmentUrl)
} else {
    let alert = UIAlertView()
    alert.title = "No internet connection detected."
    alert.addButtonWithTitle("OK")
    alert.show()

    return
}

但有没有办法检查设备是否连接到VPN?我正在编写的应用程序需要VPN才能访问,所以我不想让用户在没有连接到VPN的情况下尝试登录,而是希望先提示它们(在我看来更好的用户体验)。

感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

我正在使用下面的代码(兼容Swift 3和Swift 4)检查iOS设备上的VPN连接,这对我来说很好。在两个都使用ipsec0协议的专用VPN和ExpressVPN上进行了测试。

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
}

这也是代码的主要链接-Gist Link

答案 1 :(得分:0)

我使用以下代码使它适用于Swift 3/4:

private var isConnectedToVpn: Bool {
    if let settings = CFNetworkCopySystemProxySettings()?.takeRetainedValue() as? Dictionary<String, Any>,
        let scopes = settings["__SCOPED__"] as? [String:Any] {
        for (key, _) in scopes {
         if key.contains("tap") || key.contains("tun") || key.contains("ppp") {
                return true
            }
        }
    }
    return false
}

答案 2 :(得分:0)

ObjC:

#include <ifaddrs.h>

- (BOOL)isVPNOn
{
    BOOL flag = NO;
    NSString *version = [UIDevice currentDevice].systemVersion;
    // need two ways to judge this.
    if (version.doubleValue >= 9.0)
    {
        NSDictionary *dict = CFBridgingRelease(CFNetworkCopySystemProxySettings());
        NSArray *keys = [dict[@"__SCOPED__"] allKeys];
        for (NSString *key in keys) {
            if ([key rangeOfString:@"tap"].location != NSNotFound ||
                [key rangeOfString:@"tun"].location != NSNotFound ||
                [key rangeOfString:@"ipsec"].location != NSNotFound ||
                [key rangeOfString:@"ppp"].location != NSNotFound){
                flag = YES;
                break;
            }
        }
    }
    else
    {
        struct ifaddrs *interfaces = NULL;
        struct ifaddrs *temp_addr = NULL;
        int success = 0;

        // retrieve the current interfaces - returns 0 on success
        success = getifaddrs(&interfaces);
        if (success == 0)
        {
            // Loop through linked list of interfaces
            temp_addr = interfaces;
            while (temp_addr != NULL)
            {
                NSString *string = [NSString stringWithFormat:@"%s" , temp_addr->ifa_name];
                if ([string rangeOfString:@"tap"].location != NSNotFound ||
                    [string rangeOfString:@"tun"].location != NSNotFound ||
                    [string rangeOfString:@"ipsec"].location != NSNotFound ||
                    [string rangeOfString:@"ppp"].location != NSNotFound)
                {
                    flag = YES;
                    break;
                }
                temp_addr = temp_addr->ifa_next;
            }
        }

        // Free memory
        freeifaddrs(interfaces);
    }

    return flag;
}

ref:RealReachability/RealReachability.m - GitHub