Initialization
The Eppo iOS SDK is easy to initialize while offering robust customization options, making it adaptable to various use cases such as offline mode, custom caching requirements, and ultra-low-latency initialization.
Initialize the SDK
To complete basic initialization, you only need to provide an SDK key which you can create in the Eppo UI under Configuration > Environments > API Keys.
import EppoFlagging
Task {
try await EppoClient.initialize(sdkKey: "SDK-KEY-FROM-DASHBOARD");
}
Wrap initialization in a Task
block in order to perform network request asynchronously.
Use the SDK instance
After initialization, you can use the SDK instance by calling shared()
. You can then use the SDK instance to assign a variation to a subject using the get*Assignment
functions.
let eppoClient = EppoClient.shared()
let user = getCurrentUser()
Advanced Configuration
Basic initialization is great for most use cases, but the SDK provides options that you can use during initialization to customize the behavior of the SDK.
Initialization with Assignment Logger
When using the SDK for experiments (rather than just feature flags), you'll need to add a logging callback during initialization:
eppoClient = try await EppoClient.initialize(
sdkKey: "mock-sdk-key",
assignmentLogger: segmentAssignmentLogger
)
// Example of a simple assignmentLogger function
func segmentAssignmentLogger(assignment: Assignment) {
let assignmentDictionary: [String: Any] = [
"allocation": assignment.allocation,
"experiment": assignment.experiment,
"featureFlag": assignment.featureFlag,
"variation": assignment.variation,
"subject": assignment.subject,
"timestamp": assignment.timestamp
]
analytics.track(
name: "Eppo Assignment",
properties: TrackProperties(assignmentDictionary)
)
}
Initialization Modes
The SDK supports different initialization modes to suit your needs:
Standard Initialization
The default initialization mode fetches configurations from Eppo's CDN:
import EppoFlagging
Task {
try await EppoClient.initialize(sdkKey: "SDK-KEY-FROM-DASHBOARD");
}
Initialization with Automatic Configuration Updates (Polling)
The SDK can be configured to automatically poll for configuration updates at regular intervals. This is useful for ensuring your application always has the latest flag configurations.
To enable polling during initialization:
Task {
try await EppoClient.initialize(
sdkKey: "SDK-KEY-FROM-DASHBOARD",
pollingEnabled: true,
pollingIntervalMs: 300_000, // 5 minutes (default)
pollingJitterMs: 30_000 // 10% of polling interval (default)
)
}
You can also start and stop polling after initialization:
let eppoClient = EppoClient.shared()
// Start polling with custom intervals
try await eppoClient.startPolling(
intervalMs: 300_000, // 5 minutes
jitterMs: 30_000 // Jitter of up to 30 seconds
)
// Stop polling
eppoClient.stopPolling()
The polling mechanism includes the following features:
- Default polling interval of 5 minutes (300,000 ms)
- Random jitter to prevent thundering herd problems (default is 10% of polling interval)
- Automatic retry up to 7 times on failed requests
- Exponential backoff on failures
- Polling stops automatically if max retries are exceeded
For battery efficiency in mobile applications, it's recommended to stop polling when your app goes to the background and resume when it comes to the foreground.
Initialization with Pre-fetched Configuration
You can pass in a pre-fetched flag configuration JSON string:
Task {
try await EppoClient.initialize(
sdkKey: "SDK-KEY-FROM-DASHBOARD",
initialConfiguration: try Configuration(
flagsConfigurationJson: Data(#"{ "pre-loaded-JSON": "passed in here" }"#.utf8),
obfuscated: false
)
);
}
This will still perform a network request to fetch the latest flag configurations. The provided configuration will be used until the network request is successful.
Offline Initialization
If you'd like to initialize Eppo's client without performing a network request, you can use the initializeOffline
method:
try EppoClient.initializeOffline(
sdkKey: "SDK-KEY-FROM-DASHBOARD",
initialConfiguration: try Configuration(
flagsConfigurationJson: Data(#"{ "pre-loaded-JSON": "passed in here" }"#.utf8),
obfuscated: false
)
);
The obfuscated
parameter is used to inform the SDK if the flag configuration is obfuscated.
Offline Initialization with Configuration Management
While the basic offline initialization approach is designed for pre-loading the configuration from a server environment, some application architectures may require different approaches to configuration management. Here are two alternative approaches that provide more flexibility:
1. Using Configuration Objects Directly
You can extract the configuration object in your application and use it to initialize a new client. This approach works well when your application can maintain the configuration in memory or when transferring configurations within the same Swift application:
// Get configuration from an existing client
let configuration = existingClient.getFlagsConfiguration()
EppoClient.resetSharedInstance()
// Later, initialize a new client with the configuration object
let newClient = EppoClient.initializeOffline(
sdkKey: "SDK-KEY-FROM-DASHBOARD",
initialConfiguration: configuration
)
2. Using JSON String Serialization
The JSON string serialization approach, an alternative to the configuration object approach, is useful when:
- You need to persist configurations between app launches in platform-agnostic storage
- You need to transfer configurations through non-Swift environments or systems
// Get configuration from an existing client and convert to string
let configuration = existingClient.getFlagsConfiguration()
let configurationString = try configuration.toJsonString()
// Later, initialize a new client using the JSON string
let newClient = EppoClient.initializeOffline(
sdkKey: "SDK-KEY-FROM-DASHBOARD",
initialConfiguration: try Configuration(
flagsConfigurationJson: Data(configurationString.utf8),
obfuscated: false
)
)
These approaches provide more flexibility than basic offline initialization for when your application needs to bootstrap before network connectivity is available and maintain that state between app launches.
In both approaches, the configuration object contains all necessary information including flags, variations, and allocation rules, allowing the SDK to make assignment decisions without requiring network connectivity.
Configuration Updates
Fetching Updated Configurations
After the client has been initialized, you can use load()
to asynchronously fetch the latest flag configuration from the remote source:
try EppoClient.initializeOffline(
sdkKey: "SDK-KEY-FROM-DASHBOARD",
initialConfiguration: try Configuration(
flagsConfigurationJson: Data(#"{ "pre-loaded-JSON": "passed in here" }"#.utf8),
obfuscated: false
)
);
// Later, fetch updated configurations
Task {
try await EppoClient.shared().load();
}
As modern iOS devices have substantial memory, applications are often kept in memory across sessions. This means that the flag configurations are not automatically reloaded on subsequent launches.
It is recommended to use the load()
method to fetch the latest flag configurations when the application is launched.
Assignment Logger Schema
The SDK will invoke the logAssignment
function with an Assignment
object that contains the following fields:
timestamp
stringThe time when the subject was assigned to the variation. Example: "2021-06-22T17:35:12.000Z"
featureFlag
stringAn Eppo feature flag key. Example: "recommendation-algo"
allocation
stringAn Eppo allocation key. Example: "allocation-17"
experiment
stringAn Eppo experiment key. Example: "recommendation-algo-allocation-17"
subject
stringAn identifier of the subject or user assigned to the experiment variation. Example: UUID
subjectAttributes
[String: EppoValue]Default: [:]
A dictionary mapping String keys to EppoValue values. These attributes are used for targeting and are only logged if passed to the SDK assignment function. EppoValue can be a String, Number, or Boolean.
variation
stringDefault: undefined
The experiment variation the subject was assigned to. Example: "control"
More details about logging and examples (with Segment, Rudderstack, mParticle, and Snowplow) can be found in the assignment logging page.