I can't find a clear answer on how to do this, so that's why I created this thread. 
I'm developing a Swift application (Swift 2), where I want to connect with an VPN Server using a function. So I want to create a
func connect() {
    //Handle the connection to the VPN 
}
I received this https://gist.github.com/matthijsotterloo/cedf256f7f1c2a9a8f624481b7083afd file from the developer who made the VPN (of course I replaced certs,keys,url's and login's. Now my question is how can I connect to this VPN server in the function? I already found out I have to use the NEVPNManager but I can't really find out how to build this.
Hopefully someone can help me.
Thanks!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With