Setting up the Low Level SDK
Install the Kape Low Level Client SDK
Cloudsmith is used to provide ready-made packages and frameworks for different platforms. Cloudsmith acts as a package manager.
- Cloudsmith stable repository: https://cloudsmith.io/~expressvpn/repos/kp_client_sdk/
- Cloudsmith unstable repository: https://cloudsmith.io/~expressvpn/repos/kp_client_sdk_unstable/
Consult the Cloudsmith documentation to learn how to configure Cloudsmith as a package manager in your environment. The following environments are currently supported:
- Kotlin and Maven packages
- Swift and Swift Package Manager
- C# and NuGet packages
- Go and Go Package Manager
- C/C++ as Raw Binary
The use of the unstable build is at your own risk. Generally, we recommend using this only during the development of new features as an early preview to gather feedback on design and stability. An Unstable Build should never be used in a production environment.
Configure and Initialize
The SDK Manager serves as the core hub of the SDK, handling dependencies, configurations, and offering interfaces to access various SDK modules.
Here's a detailed guide for setting up and initializing the SDK step-by-step.
Implementing Callback Interfaces
The SDK is cross-platform, but it relies on native apps for specific functionalities. For example, it uses the platform's native secure storage, like Apple's Keychain, to securely store sensitive information such as tokens. It will use a callback interface, to let the native apps implement the storage.
StorageCallbackProtocol
Apps need to implement the StorageCallbackProtocol to let the SDK securely store credential information such as
Authorization Tokens.
- Swift
- Kotlin
public protocol StorageCallbackProtocol : AnyObject {
func storeData(storageId: String, data: Data) throws
func retrieveData(storageId: String) throws -> Data?
}
interface StorageCallbackProtocol {
fun storeData(storageId: String, data: ByteArray)
fun retrieveData(storageId: String): ByteArray?
}
| Parameter | Description |
|---|---|
storageId | Unique id for this storage item |
data | Data to be stored |
In case there is a problem to access the storage, the app must return a SdkException.Storage exception.
LogCallbackProtocol
Additionally apps can provide the LogCallbackProtocol to receive log events from the SDK process them.
- Swift
- Kotlin
public protocol LogCallbackProtocol : AnyObject {
func log(
logLevel: CallbackLogLevel,
category: String,
file: String,
line: UInt32,
message: String
) throws
}
interface LogCallbackProtocol {
@Throws(Exception::class)
fun log(
logLevel: CallbackLogLevel,
category: String,
file: String,
line: UInt,
message: String
)
}
| Parameter | Description |
|---|---|
logLevel | Log level of that event |
category | A category this event belongs to |
file | Source file name this log line got triggered |
message | The log message |
StateCallbackProtocol
The primary use case for implementing this protocol is to receive notifications about specific state changes within the
SDK. For instance, if the SDK detects that credentials have expired, prompting the user to log in again, it checks
whether the state equals LibState::LoggedOut. The method can return whether the SDK should proceed in certain states;
for example, when encountering LibState::LoggedOut, simply return true.
- Swift
- Kotlin
public protocol StateCallbackProtocol : AnyObject {
func processState(state: LibState)-> bool throws
}
interface StateCallbackProtocol {
fun processState(state: LibState): bool
}
Creating the Base Configuration
After having implemented the callback clients, you can continue to setup a base configuration.
For internal logging reasons, you will need to call setClientDetails providing an object with details about your app.
ClientDetails
| Property | Description |
|---|---|
os | The operating system of the client. One of the following variants:
|
osVersion | The version of the Operating System |
appVersion | The version of the app |
deviceModel | The model of the device e.g. "iPhone 16 Pro Max", if available. |
openIdClientId | This is the OpenID client id in case you will use OpenID to authenticate the SDK. This makes sure, that the SDK can internally refresh tokens properly. |
Cache File Path
The SDK will internally cache few information, like responses and other things using a file cache. Apps need to provide a location, which is read- and writable. That folder must already exist.
- Swift
- Kotlin
let configuration = Configuration()
configuration.setClientDetails(details: clientDetails)
// This might throw an exception in case the path is invalid or not writable
try configuration.setCacheFilePath(cacheFilePath: <Path>)
// Activate the SDK License
try configuration.setLicense(
license: "Content of the License File we provided to you"
)
// Register the Callbacks
configuration.setStorageCallback(callback: StorageClient())
configuration.setLogCallback(callback: LogClient())
val configuration = Configuration()
configuration.setClientDetails(clientDetails)
// This might throw an exception in case the path is invalid or not writable
configuration.setCacheFilePath(cacheFilePath: <Path>)
// Activate the SDK License
configuration.setLicense("Content of the License File we provided to you")
// Register the Callbacks
configuration.setStorageCallback(StorageClient())
configuration.setLogCallback(LogClient())
Loading Configuration Details
You will be provided with a custom configuration file, which contains additional configuration settings required for your specific implementation. Once you created the base configuration, you must load these additional details.
You might later adjust the log level using setMaxLogLevel .
- Swift
- Kotlin
sdkConfiguration.loadFromYaml(
yamlContent: "content of the YAML configuration file"
)
sdkConfiguration.loadFromYaml(
yamlContent = "content of your configuration file"
)
Initializing the SDK Manager
Now we can continue and initialize the SDK Manager.
- Swift
- Kotlin
let manager = try SdkManager(configuration: sdkConfiguration)
val manager = runCatching { SdkManager(configuration = sdkConfiguration) }
Authenticating the SDK
Before being able to call most of the methods in the SDK, the SDK needs to be authenticated, move on to the Authentication Module, to learn, which Authentication Method you need to use.