Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Connect to VPN programmatically in iOS 8

Since the release of iOS 8 beta, I found a Network Extension framework in its bundle which is going to let developers configure and connect to VPN servers programmatically and without any profile installation.

The framework contains a major class called NEVPNManager. This class also has 3 main methods that let me save, load or remove VPN preferences. I’ve written a piece of code in viewDidLoad method as following:

NEVPNManager *manager = [NEVPNManager sharedManager]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(vpnConnectionStatusChanged) name:NEVPNStatusDidChangeNotification object:nil]; [manager loadFromPreferencesWithCompletionHandler:^(NSError *error) {     if(error) {         NSLog(@"Load error: %@", error);     }}]; NEVPNProtocolIPSec *p = [[NEVPNProtocolIPSec alloc] init]; p.username = @“[My username]”; p.passwordReference = [KeyChainAccess loadDataForServiceNamed:@"VIT"]; p.serverAddress = @“[My Server Address]“; p.authenticationMethod = NEVPNIKEAuthenticationMethodCertificate; p.localIdentifier = @“[My Local identifier]”; p.remoteIdentifier = @“[My Remote identifier]”; p.useExtendedAuthentication = NO; p.identityData = [My VPN certification private key]; p.disconnectOnSleep = NO; [manager setProtocol:p]; [manager setOnDemandEnabled:NO]; [manager setLocalizedDescription:@"VIT VPN"]; NSArray *array = [NSArray new]; [manager setOnDemandRules: array]; NSLog(@"Connection desciption: %@", manager.localizedDescription); NSLog(@"VPN status:  %i", manager.connection.status); [manager saveToPreferencesWithCompletionHandler:^(NSError *error) {    if(error) {       NSLog(@"Save error: %@", error);    } }]; 

I also placed a button in my view and set its TouchUpInside action to the method below:

- (IBAction)buttonPressed:(id)sender {    NSError *startError;    [[NEVPNManager sharedManager].connection startVPNTunnelAndReturnError:&startError];    if(startError) {       NSLog(@"Start error: %@", startError.localizedDescription);    } } 

There are two problems here:

1) When I try to save the preferences, the following error will be thrown: 
Save error: Error Domain=NEVPNErrorDomain Code=4 "The operation couldn’t be completed. (NEVPNErrorDomain error 4.)”
What is this error? How can I solve this issue?

2) [[NEVPNManager sharedManager].connection startVPNTunnelAndReturnError:&startError]; method doesn’t return any error when I call it but the connection status changes from Disconnected to Connecting for just a moment and then it gets back to Disconnected state.

Any help will be appreciated :)

like image 783
Mohammad M. Ramezanpour Avatar asked Jul 26 '14 10:07

Mohammad M. Ramezanpour


People also ask

How do I get my iPhone to automatically connect to VPN?

On iOS. Go to your app Settings and select VPN connection. Tap Auto-Connect. Select if you want to enable auto-connect on Wi-Fi or always.

Does iOS have built in VPN?

With the Personal VPN feature in macOS and iOS, your app can create and manage a VPN configuration that uses one of the built-in VPN protocols (IPsec or IKEv2). The user must explicitly authorize your app the first time it saves a VPN configuration.


1 Answers

The problem is the error you are getting when saving: Save error: Error Domain=NEVPNErrorDomain Code=4

If you look in the NEVPNManager.h header file, you will see that error code 4 is "NEVPNErrorConfigurationStale". The configuration is stale and needs to be loaded. You should call loadFromPreferencesWithCompletionHandler: and in the completion handler modify the values you want to modify, and then call saveToPreferencesWithCompletionHandler:. The example in your question is modifying the configuration before the loading is completed, which is why you are getting this error.

More like this:

[manager loadFromPreferencesWithCompletionHandler:^(NSError *error) {      // do config stuff      [manager saveToPreferencesWithCompletionHandler:^(NSError *error) {      }]; }]; 
like image 95
quellish Avatar answered Sep 20 '22 15:09

quellish