NEVPNManager Connect to VPN in Swift

柔情痞子 提交于 2019-12-03 03:51:33

It's a little confusing but you setup a configuration with the desired parameters and then save that configuration to the NEVPNManager. After that start VPN tunneling.

So you would have something like:

    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()
        }
     }

It is also nonobvious but important that you nest the completion handlers properly:

    loadFromPreferencesWithCompletionHandler{ 
        ...
        saveToPreferencesWithCompletionHandler{ 
            startVPNTunnel 
        }
    }

passwordRef is:

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

and vpnAccount.persistentRef is:

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
}

I don't recall the details but seem to remember that the above was pretty important regarding creating the ref that NEVPNManager is looking for.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!