【问题标题】:NEVPNManager Connect to VPN in SwiftNEVPNManager 在 Swift 中连接到 VPN
【发布时间】:2017-01-03 06:33:31
【问题描述】:

我找不到关于如何做到这一点的明确答案,所以这就是我创建这个线程的原因。
我正在开发一个 Swift 应用程序 (Swift 2),我想在其中使用一个函数连接一个 VPN 服务器。所以我想创建一个

func connect() {
    //Handle the connection to the VPN 
}

我从创建 VPN 的开发人员那里收到了这个 https://gist.github.com/matthijsotterloo/cedf256f7f1c2a9a8f624481b7083afd 文件(当然我替换了证书、密钥、url 和登录名。现在我的问题是如何在函数中连接到这个 VPN 服务器?我已经找到了我必须使用 NEVPNManager,但我真的不知道如何构建它。

希望有人可以帮助我。

谢谢!

【问题讨论】:

    标签: ios swift ios9 vpn nevpnmanager


    【解决方案1】:

    这有点令人困惑,但是您使用所需的参数设置了配置,然后将该配置保存到 NEVPNManager。之后启动 VPN 隧道。

    所以你会有类似的东西:

        NEVPNManager.sharedManager().loadFromPreferencesWithCompletionHandler { error in
            // setup the config:
            let password = vpnAccount!.vpnPassword          
            let vpnhost = vpnAccount!.vpnHost
            let p = NEVPNProtocolIKEv2()
            p.username = username
            p.localIdentifier = username
            p.serverAddress = vpnhost
            p.remoteIdentifier = vpnhost
            p.authenticationMethod = .None
            p.passwordReference = passwordRef
            p.useExtendedAuthentication = true
            p.serverCertificateIssuerCommonName = vpnhost
            p.disconnectOnSleep = false
    
    
            var rules = [NEOnDemandRule]()
            let rule = NEOnDemandRuleConnect()
            rule.interfaceTypeMatch = .Any
            rules.append(rule)
    
            NEVPNManager.sharedManager().localizedDescription = "My VPN"
            NEVPNManager.sharedManager().protocolConfiguration = p
            NEVPNManager.sharedManager().onDemandRules = rules
            NEVPNManager.sharedManager().onDemandEnabled = true
            NEVPNManager.sharedManager().enabled = true
            NEVPNManager.sharedManager().saveToPreferencesWithCompletionHandler { error in
                guard error == nil else {
                    print("NEVPNManager.saveToPreferencesWithCompletionHandler failed: \(error!.localizedDescription)")
                    return
                }
                VPNManager.sharedManager.startVPNTunnel()
            }
         }
    

    正确嵌套完成处理程序也是不明显但很重要的:

        loadFromPreferencesWithCompletionHandler{ 
            ...
            saveToPreferencesWithCompletionHandler{ 
                startVPNTunnel 
            }
        }
    

    密码参考是:

                    let password = vpnAccount!.vpnPassword
                    vpnAccount!.setPersistenRef(username, password: password!)
                    let passwordRef = vpnAccount!.persistentRef
    

    而 vpnAccount.persistentRef 是:

    class func persistentRef(_ key: String) -> Data? {
        let query: [AnyHashable: Any] = [
            kSecClass as AnyHashable: kSecClassGenericPassword,
            kSecAttrGeneric as AnyHashable: key,
            kSecAttrAccount as AnyHashable: key,
            kSecAttrAccessible as AnyHashable: kSecAttrAccessibleAlways,
            kSecMatchLimit as AnyHashable: kSecMatchLimitOne,
            kSecAttrService as AnyHashable: Bundle.main.bundleIdentifier!,
            kSecReturnPersistentRef as AnyHashable: kCFBooleanTrue
        ]
    
        var secItem: AnyObject?
        let result = SecItemCopyMatching(query as CFDictionary, &secItem)
        if result != errSecSuccess {
            return nil
        }
    
        return secItem as? Data
    }
    

    我不记得细节,但似乎记得上面对于创建 NEVPNManager 正在寻找的 ref 非常重要。

    【讨论】:

    • +1。对此还有两点说明。它在几个地方提到。好的做法是在保存后重新加载首选项(它解决了一些问题)。还有startVPNTunnel会抛出,也需要处理。
    • 这里的“passwordRef”是什么?
    • 我是 Swift 的菜鸟,你能告诉我 vpnAccount 的定义在哪里吗?
    • 大家好,你们有没有找到任何 VPN 解决方案。我需要在我的受监督设备中触发 VPN 连接。需要帮助吗?
    猜你喜欢
    • 2016-02-28
    • 1970-01-01
    • 2018-07-20
    • 1970-01-01
    • 2021-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-14
    相关资源
    最近更新 更多