Reconnection strategy
When building iOS applications that rely on a VPN connection, implementing a robust reconnection strategy is crucial to ensure a seamless user experience. One effective approach is to leverage the On-Demand VPN feature, which allows the system to automatically establish the VPN connection based on predefined rules. In this page, we'll explore how to configure On-Demand VPN using the OnDemandConfiguration
struct in Swift and how it ties into a reliable reconnection strategy.
Understanding OnDemandConfiguration
The OnDemandConfiguration
struct is a codable struct that represents the configuration for On-Demand VPN. It has two main properties:
isEnabled
A boolean value that determines whether the On-Demand VPN feature is enabled or not.
The default value for this setting is
false
. When set tofalse
, the on-demand rules for automatically reconnecting the VPN are disabled. This means that the VPN will not automatically reconnect based on any rules. In this case, the user must manually manage the VPN connection.When set to
true
, the VPN will be automatically triggered by the system after thestartVPN
method is called. To disable On-Demand VPN, you need to call thestop
method from your application.
onDemandRules
Defines the rules for triggering the On-Demand VPN connection. These rules specify the conditions under which the VPN should be activated.
If no custom rules are provided,
OnDemandConfiguration
uses the default rules defined in theNEOnDemandRule.defaultRules
property fromNetworkExtension
.You can customize the On-Demand rules based on your specific requirements. For example, you can create rules based on type of network interface (WiFi, cellular, etc), or other criteria supported by the
NEOnDemandRule
class.
Sample Codes
import NetworkExtension
// ...
// Create custom on-demand rules
let connectRuleWifi = NEOnDemandRuleConnect()
connectRuleWifi.interfaceTypeMatch = .wiFi
let disconnectRuleCellular = NEOnDemandRuleDisconnect()
disconnectRuleCellular.interfaceTypeMatch = .cellular
let onDemandRules = [connectRuleWifi, disconnectRuleCellular]
let hydraConfiguration = HydraConfiguration(
carrierID: "YOUR_CARRIER_ID",
extensionBundleID: "com.yourcompany.demo-test.app.hydra-extension",
groupData: VPNGroupData(
groupID: "group.GROUP_ID",
usesSystemExtension: false
),
fireshieldConfig: FireshieldConfig(
mode: .disabled,
groupData: VPNGroupData(groupID: "group.com.yourcompany.vpnsdk-demo", usesSystemExtension: false)
),
onDemandConfiguration: OnDemandConfiguration(isEnabled: true, onDemandRules: onDemandRules)
)
In the sample code above:
import NetworkExtensions
imports the NetworkExtension framework, which provides APIs for configuring and managing VPN connections.Two on-demand rules are created:
connectRuleWifi
: Specifies that the VPN should automatically connect when the device is connected to a Wi-Fi network.disconnectRuleCellular
: Specifies that the VPN should automatically disconnect when the device switches to a cellular network.
The
HydraConfiguration
object is initialized with various configuration parameters, including theonDemandConfiguration
property.The
OnDemandConfiguration
object is created withisEnabled
set totrue
, enabling the on-demand rules, and theonDemandRules
array is passed as theonDemandRules
parameter.
SDK Implementation and Limitations
Current Implementation Behavior
Our SDK implementation prioritizes explicit VPN control to ensure predictable behavior. The SDK automatically manages On Demand functionality in conjunction with the start()
and stop()
methods:
On
start()
: The VPN connection is established according to your configurationOn
stop()
: The SDK automatically disables On Demand by:Setting
isOnDemandEnabled
tofalse
Saving this configuration to system preferences
Preventing any automatic reconnection based on On Demand rules
This design ensures that when users explicitly stop the VPN, it remains stopped without unexpected reconnections.
Workaround for Persistent On Demand
If your application requires On Demand to remain active even after calling stop()
, you can implement a workaround using direct access to Apple's NetworkExtension API. This approach bypasses the SDK's automatic On Demand management.
Implementation Steps
Configure and start the VPN profile using the SDK as normal
After SDK configuration, access the
NETunnelProviderManager
directlyManually enable both On Demand and the VPN profile
Save the configuration to system preferences
Important Considerations
Manual Management Required: When using this workaround, you become responsible for managing On Demand state
SDK
stop()
Behavior: The SDK'sstop()
method will still attempt to disable On Demand, so you may need to re-enable it after stoppingSystem Behavior: iOS/macOS will continue attempting to connect based on your On Demand rules, even if the VPN encounters errors
User Experience: Consider implementing UI controls to allow users to fully disable On Demand when needed
Last updated
Was this helpful?