Below I will give an example of my connection code.
objective-c
#import Foundation/Foundation.h
@import NetworkExtension;
@import OpenVPNAdapter;
NS_ASSUME_NONNULL_BEGIN
@interface VPNManager : NSObject
@property(strong,nonatomic) NETunnelProviderManager *providerManager;
// Properties has data/string from .ovpn file
@property(strong,nonatomic) NSData* configData;
// Ip addres of server from json
@property(strong,nonatomic) NSString* remoteIp;
(instancetype)sharedInstance;
(void) loadProviderManager;
(void) uninstallVPNConfigurationFromManagers;
(void) startConnection:(void(^)(void))completion;
(void) stopConnection:(void(^)(void))completion;
@end
NS_ASSUME_NONNULL_END
objective-c
#import "VPNManager.h"
#import os/log.h
@interface VPNManager ()
@property os_log_t log;
@end
@implementation VPNManager
@synthesize log;
/*
Method initialize 'NETunnelProviderManager *providerManager' ---------------------------------------------------------------------------------------------------------*/
(void) loadProviderManager
{
__weak typeof(self) weak = self;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
weak.log = os_log_create("secretVPN.com.VPNClient.iOSPacketTunnel", "ios_app");
});
[NETunnelProviderManager loadAllFromPreferencesWithCompletionHandler:^(NSArrayNETunnelProviderManager** _Nullable managers, NSError* _Nullable error) {
if(error){
NSLog(@"loadAllFromPreferencesWithCompletionHandler error: %@",error); return;
}
if (managers.count 1) {
[weak uninstallVPNConfigurationFromManagers];
}
weak.providerManager = managers.firstObject ? managers.firstObject : [NETunnelProviderManager new];
[weak.providerManager loadFromPreferencesWithCompletionHandler:^(NSError * _Nullable error) {
if(error){
NSLog(@"weak.providerManager loadAllFromPreferencesWithCompletionHandler error: %@",error); return;
}
NETunnelProviderProtocol *tunnelProtocol = [weak createProtocolConfiguration];
weak.providerManager.protocolConfiguration = tunnelProtocol;
weak.providerManager.localizedDescription = @"secretVPN";
weak.providerManager.enabled = YES;
weak.providerManager.onDemandEnabled = NO;
[weak.providerManager saveToPreferencesWithCompletionHandler:^(NSError *error) {
NSLog(@"%@", (error) ? @"Saved with error" : @"Save successfully");
if(error) return;
}];
}];
}];
}
/*
Unistall managers ---------------------------------------------------------------------------------------------------------*/
(void) uninstallVPNConfigurationFromManagers
{
[NETunnelProviderManager loadAllFromPreferencesWithCompletionHandler:^(NSArrayNETunnelProviderManager** _Nullable managers, NSError * _Nullable error) {
if (error != nil) {
os_log_debug(self.log, "ERROR Uninstall vpn config: %{public}@", error.localizedDescription);
return;
}
for (NETunnelProviderManager *manager in managers) {
[manager removeFromPreferencesWithCompletionHandler:^(NSError * _Nullable error) {
if (error != nil) {
os_log_debug(self.log, "ERROR Uninstall vpn config: %{public}@", error.localizedDescription);
return;
} else {
os_log_debug(self.log, "Successful uninstall %{public}@", manager.description);
}
}];
}
os_log_debug(self.log, "Uninstalled vpn config");
}];
}
/*
Start connection ---------------------------------------------------------------------------------------------------------*/
(void) startConnection:(void(^)(void))completion
{
__weak typeof(self) weak = self;
[self.providerManager loadFromPreferencesWithCompletionHandler:^(NSError * _Nullable error) {
if(error){
NSLog(@"weak.providerManager loadAllFromPreferencesWithCompletionHandler error: %@",error); return;
}
[weak.providerManager.connection startVPNTunnelAndReturnError:&error];
NSLog(@"%@", (error) ? @"Saved with error" : @"Connection established!");
}];
}
/*
Stop connection ---------------------------------------------------------------------------------------------------------*/
(void) stopConnection:(void(^)(void))completion
{
__weak typeof(self) weak = self;
[self.providerManager loadFromPreferencesWithCompletionHandler:^(NSError * _Nullable error) {
if(error){
NSLog(@"weak.providerManager loadAllFromPreferencesWithCompletionHandler error: %@",error); return;
}
[weak.providerManager.connection stopVPNTunnel];
NSLog(@"stopVPNTunnel");
}];
}
/*
Create providerProtocols ---------------------------------------------------------------------------------------------------------*/
(NETunnelProviderProtocol*) createProtocolConfiguration
{
NETunnelProviderProtocol *tunel = [[NETunnelProviderProtocol alloc] init];
tunel.serverAddress = self.remoteIp;
tunel.providerBundleIdentifier = @"secretVPN.com.VPNClient.iOSPacketTunnel";
tunel.providerConfiguration = @{ @"ovpn" : self.configData };
tunel.disconnectOnSleep = NO;
return tunel;
}
#pragma mark - Helpers
/*
Convert Connection.Status to NSString ---------------------------------------------------------------------------------------------------------*/
(void)onVpnStateChange:(NSNotification *)Notification {
switch (self.providerManager.connection.status) {
case NEVPNStatusInvalid:
NSLog(@"NEVPNStatusInvalid");
break;
case NEVPNStatusDisconnected:
NSLog(@"NEVPNStatusDisconnected");
break;
case NEVPNStatusConnecting:
NSLog(@"NEVPNStatusConnecting");
break;
case NEVPNStatusConnected:
NSLog(@"NEVPNStatusConnected");
break;
case NEVPNStatusDisconnecting:
NSLog(@"NEVPNStatusDisconnecting");
break;
case NEVPNStatusReasserting:
NSLog(@"******************ReConnecting****************");
break;
default:
break;
}
}