5

我需要以编程方式检测 iphone 是否连接到 VPN。我正在开发一个尝试加载 URL 的应用程序,此页面仅在设备连接到 VPN 时打开。在加载此 URL 之前,我需要检查 VPN 连接。我尝试了以下 . 但这并没有按预期工作。

- (BOOL)checkForVPNConnectivity {
  NSDictionary *dict = (__bridge NSDictionary *)(CFNetworkCopySystemProxySettings());
  //NSLog(@"cfnetwork proxy setting : %@", dict);
  return [dict count] > 0; 
 }
4

4 回答 4

6

我不认为应该通过检查CFNetworkCopySystemProxySettings(). (例如,我在 WiFi 网络上看到条目,但在 VPN 上看不到。)

因此,有两个观察结果:

  1. 我会考虑SystemConfiguration.framework在您的 VPN 上使用并使用以下代码和主机名:

    - (BOOL)checkForConnectivity:(NSString *)hostName
    {
        BOOL success = false;
    
        SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]);
        SCNetworkReachabilityFlags flags;
        success = SCNetworkReachabilityGetFlags(reachability, &flags);
        CFRelease(reachability);
    
        NSLog(@"success=%x", flags);
    
        // this is the standard non-VPN logic, you might have to alter it for VPN connectivity
    
        BOOL isAvailable = success && (flags & kSCNetworkFlagsReachable) && !(flags & kSCNetworkFlagsConnectionRequired);
        if (isAvailable) {
            NSLog(@"Host is reachable: %d", flags);
            return YES;
        }else{
            NSLog(@"Host is unreachable");
            return NO;
        }
    }
    

    假设它success不为零,您可能需要对flags. 有关这些标志的技术定义,请参阅SCNetworkReachability Reference。我听说他们会kSCNetworkReachabilityFlagsReachable | kSCNetworkReachabilityFlagsTransientConnection在连接 VPN 时获得,但我没有 VPN,所以我无法测试该说法。我建议在启用和不启用 VPN 的情况下尝试它,看看您是否得到不同的flags回报。

  2. 与手头的问题无关,您的代码示例会泄漏。如果使用 ARC,请不要忘记使用CFBridgingReleaseor __bridge_transfer。或者无论是否在 ARC 中,CFRelease在返回之前显式调用。

    如果您在最新版本的 Xcode 中运行静态分析器(按shift++或从“产品”菜单中选择“分析” commandB,它应该会警告您有关 Core Foundation 调用的内存管理。

    无论如何,这就是我倾向于在 ARC 中处理它的方式:

    - (BOOL)checkForVPNConnectivity
    {
        NSDictionary *dict = CFBridgingRelease(CFNetworkCopySystemProxySettings());
    
        return [dict count] > 0;
    }
    
于 2013-04-29T18:19:07.290 回答
1

使用这种方法简单就可以实现。自 iOS 12 和 iOS 13 起,按键列表已更改

增加了 2 把钥匙

utun1 和 utun2

所以函数应该是:

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

}

于 2021-05-10T11:05:47.353 回答
0

您可以对上述问题使用简单的解决方法。

只需使用苹果可达性来检查 ios 设备是否连接到互联网。如果没有抛出没有互联网连接错误。如果是,请尝试使用 NSURLConnection 访问您的 VPN 相关 URL。如果您获得成功 200,即您已连接到 VPN。如果此请求返回未找到主机或任何错误,如 -1001 表示你没有连接到 VPN。然后你可以向用户抛出相应的 VPN 连接错误。快乐编码.... Arun kumar

更多信息请参考我的博客 http://aruntheiphonedeveloper.blogspot.in

于 2015-02-14T08:14:40.070 回答
0
let connect=ConnectVPN()
        connect.loadFromPreference()
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            let status=NEVPNManager.shared().connection.status
            print(status)
        }

负载偏好在哪里

 public func loadFromPreference(){
        do {
            try self.vpnManager.loadFromPreferences(completionHandler: {
                error in
            })

        } catch let error {
            print("Could not start VPN Connection: \(error.localizedDescription)" )
        }
    }

然后在状态中,您会获得已断开、无效和已连接等的 vpn 状态,您可以从此链接https://developer.apple.com/documentation/networkextension/nevpnstatus阅读有关它的信息, 希望这会帮助您愉快地编码:)

于 2018-05-02T05:25:40.950 回答