Skip to main content

Getting Started

This guide walks you through the complete flow: initializing the SDK, authenticating, browsing VPN servers, and establishing a VPN connection.

1. Initialize the SDK​

All configuration lives in KapeSDK.plist (see Installation). Initialization is two lines:

import KapeCore

let settings = try KapeSDKSettings() // reads KapeSDK.plist
let handle = try KapeSdkHandle(settings: settings) // initializes the Low Level SDK

Keep the handle alive for the lifetime of your app. All other SDK objects reference it.

2. Authenticate​

import KapeAuth

let auth = KapeAuthClient(handle: handle)

// iOS — requires a presenting UIViewController
try await auth.login(presenting: viewController)

// Check the session — `displayName` is nil when there is nothing to show (a guest, say)
if let session = await auth.currentAuthenticationSession() {
print("Logged in as \(session.displayName ?? "an unnamed user")")
}
warning

You must forward incoming URLs via onOpenURL (SwiftUI) or scene(_:openURLContexts:) (UIKit). The OpenID Connect redirect will not complete otherwise.

.onOpenURL { url in
auth.handleCallbackURL(url)
}

3. Observe Auth State​

auth.authState
.sink { state in
switch state {
case .authenticated:
// show home screen
case .unauthenticated:
// show login screen
}
}
.store(in: &cancellables)

4. Activate Subscription​

After authentication, activate the subscription to unlock VPN features:

try await handle.activateSubscription(for: .custom(values: ["xv.vpn"]))

5. Browse VPN Locations​

import KapeVPN

let locations = KapeLocationService(handle: handle)
try await locations.fetchLocations()

// Locations grouped by continent
for (continent, servers) in locations.locationsByContinent {
print("\(continent):")
for server in servers {
print(" \(server.name) (\(server.country))")
}
}

6. Connect to VPN​

let vpn = KapeVPNManager(handle: handle)

// Install the VPN profile (shows system permission dialog on first call)
try await vpn.installProfile()

// Connect to a location
try await vpn.connect(to: locationId)

// Observe connection status
vpn.$connectionStatus
.sink { status in
print(status) // .connecting, .connected, .disconnecting, .disconnected
}
.store(in: &cancellables)

7. Disconnect​

await vpn.disconnect()

8. Log Out​

try await auth.logout()

Example Apps​

The SDK repository includes complete working examples:

  • VPNDemo — Full VPN app with authentication, server list, and WireGuard connectivity
  • AuthDemo — Authentication-only example

See the apple/Examples/ directory in the SDK repository.

Next Steps​

  • Authentication — login, logout, sessions, and error handling
  • VPN — server discovery, connection management, and Network Extension setup
  • Logs Collector — uploading logs for support, or exporting them to a file