Skip to content

API

This section documents all APIs of experiments and events. The methods are only available through Ascend. To get all the methods, use following:

// This returns the object which contains all the methods
let experiments = try Ascend.getPlugin(AscendExperiments.self)
// Print this object to see what are available methods here
print(experiments)

MethodReturn Type
getBoolValue(for:with:dontCache:ignoreCache:)Bool
getIntValue(for:with:dontCache:ignoreCache:)Int
getDoubleValue(for:with:dontCache:ignoreCache:)Double
getLongValue(for:with:dontCache:ignoreCache:)Int64
getStringValue(for:with:dontCache:ignoreCache:)String
getAllVariablesJSON(for:)String?
getExperimentVariants()[String: ExperimentVariant]
getExperimentVariantsJSON()String?
getExperimentsFromStorage()[String: Experiment]?
fetchExperiments(for:completion:)Void (completion handler)
refreshExperiments(completion:)Void (completion handler)
setExperimentsToStorage(_:)Void
getDefaultExperimentValues()[String: ExperimentVariable]
loadExperimentsData(completion:)Void (completion handler)
clearAllExperimentsData()Void

Retrieves a boolean value from an experiment

Parameters:

  • for experimentKey: The experiment identifier (e.g., “feature_toggle”)
  • with variable: Variable name within the experiment (required)
  • dontCache: If true, doesn’t cache the result in memory (default: false)
  • ignoreCache: If true, bypasses the cache and fetches fresh (default: false)

Returns: Boolean value with fallback to false

Fallback Order:

  1. Accessed cache (if ignoreCache = false)
  2. Experiment map (fetched from server)
  3. Default map (provided at initialization)
  4. Hard-coded false

Example:

let experiments = try Ascend.getPlugin(AscendExperiments.self)
let isEnabled = experiments.getBoolValue(for: "feature_toggle", with: "enabled")

Retrieves an integer value from an experiment

Parameters:

  • for experimentKey: The experiment identifier (e.g., “retry_config”)
  • with variable: Variable name within the experiment (required)
  • dontCache: If true, doesn’t cache the result in memory (default: false)
  • ignoreCache: If true, bypasses the cache and fetches fresh (default: false)

Returns: Integer value with fallback to -1

Fallback Order:

  1. Accessed cache (if ignoreCache = false)
  2. Experiment map (fetched from server)
  3. Default map (provided at initialization)
  4. Hard-coded -1

Example:

let experiments = try Ascend.getPlugin(AscendExperiments.self)
let maxAttempts = experiments.getIntValue(for: "retry_config", with: "max_attempts")

Retrieves a double value from an experiment

Parameters:

  • for experimentKey: The experiment identifier (e.g., “network_config”)
  • with variable: Variable name within the experiment (required)
  • dontCache: If true, doesn’t cache the result in memory (default: false)
  • ignoreCache: If true, bypasses the cache and fetches fresh (default: false)

Returns: Double value with fallback to -1.0

Fallback Order:

  1. Accessed cache (if ignoreCache = false)
  2. Experiment map (fetched from server)
  3. Default map (provided at initialization)
  4. Hard-coded -1.0

Example:

let experiments = try Ascend.getPlugin(AscendExperiments.self)
let timeout = experiments.getDoubleValue(for: "network_config", with: "timeout")

Retrieves a long (Int64) value from an experiment

Parameters:

  • for experimentKey: The experiment identifier (e.g., “cache_config”)
  • with variable: Variable name within the experiment (required)
  • dontCache: If true, doesn’t cache the result in memory (default: false)
  • ignoreCache: If true, bypasses the cache and fetches fresh (default: false)

Returns: Int64 value with fallback to -1

Fallback Order:

  1. Accessed cache (if ignoreCache = false)
  2. Experiment map (fetched from server)
  3. Default map (provided at initialization)
  4. Hard-coded -1

Example:

let experiments = try Ascend.getPlugin(AscendExperiments.self)
let ttl = experiments.getLongValue(for: "cache_config", with: "ttl")

Retrieves a string value from an experiment

Parameters:

  • for experimentKey: The experiment identifier (e.g., “button_exp_test”)
  • with variable: Variable name within the experiment (required)
  • dontCache: If true, doesn’t cache the result in memory (default: false)
  • ignoreCache: If true, bypasses the cache and fetches fresh (default: false)

Returns: String value with fallback to "" (empty string)

Fallback Order:

  1. Accessed cache (if ignoreCache = false)
  2. Experiment map (fetched from server)
  3. Default map (provided at initialization)
  4. Hard-coded "" (empty string)

Example:

let experiments = try Ascend.getPlugin(AscendExperiments.self)
let color = experiments.getStringValue(for: "button_exp_test", with: "color")

Retrieves all variables for a specific experiment as a JSON string

Parameters:

  • for experimentKey: The experiment identifier

Returns: String? containing JSON representation of all variables, or nil if not found

Fallback Order:

  1. Experiment map (fetched from server)
  2. Default map (provided at initialization)
  3. nil

Example:

let experiments = try Ascend.getPlugin(AscendExperiments.self)
if let jsonString = experiments.getAllVariablesJSON(for: "button_exp_test") {
print("Variables: \(jsonString)")
}

Fetches experiments from the backend server.

Parameters:

  • for experimentKeys: Dictionary of experiment keys with their default values (e.g., ["button_color": .dictionary(["color": .string("blue")])])
  • completion: Completion handler with (ExperimentResponse?, String?) parameters

Behavior:

  • Appends the provided default values to the default map
  • Triggers network requests to fetch the experiments
  • API CALL - POST request to /v1/allocations endpoint (or configured apiEndpoint)

API Request Details:

  • Method: POST
  • Endpoint: Configured apiEndpoint (default: /v1/users/experiments, but commonly /v1/allocations)
  • Headers:
    • api-key: From configuration headers
    • user-id: Current user ID (if available)
    • guest-id: Current guest ID
    • content-type: application/json
    • Custom headers from configuration
  • Body: JSON payload with experiment_keys, stable_id, user_id, and attributes

On Success:

  • Updates experiment map with fetched experiments
  • Removes experiments not in defaultExperiments
  • Persists experiment map to local storage
  • Calls completion handler with ExperimentResponse containing fetched experiments

On Error:

  • Calls completion handler with nil response and error string

Example:

let experiments = try Ascend.getPlugin(AscendExperiments.self)
experiments.fetchExperiments(for: [
"button_color": .dictionary([
"color": .string("blue")
])
]) { response, error in
if let error = error {
print("Error: \(error)")
} else if let response = response {
print("Fetched \(response.data?.count ?? 0) experiments")
}
}

Fetches experiments using predefined experiment keys in the default map

Parameters:

  • completion: Completion handler with (ExperimentResponse?, String?) parameters

Behavior:

  • Uses existing default experiments (from configuration) to refresh
  • Builds request from keys of the defaultExperiments map
  • Triggers network request to fetch experiments
  • API CALL - Same as fetchExperiments but uses default map keys

On Success:

  • If shouldRefreshOnForeground is true, updates caching headers (e.g., cache window/last modified) from the response
  • Parses response to Experiment array and updates experiment map
  • Removes experiments not present in defaultExperiments
  • Persists experiment map to local storage
  • Calls completion handler with ExperimentResponse (on main thread)

On Error or Exception:

  • Processes error (including 304 Not Modified handling) and calls completion handler with nil response and error string (on main thread)

Example:

let experiments = try Ascend.getPlugin(AscendExperiments.self)
experiments.refreshExperiments { response, error in
if let error = error {
print("Error: \(error)")
} else if let response = response {
print("Refreshed \(response.data?.count ?? 0) experiments")
}
}

Returns a copy of all currently loaded experiment variants

Parameters:

  • None

Returns: [String: ExperimentVariant] where:

  • Key: experimentKey (experiment identifier)
  • Value: ExperimentVariant object containing:
    • experimentId: Unique experiment identifier
    • variantName: Name of the assigned variant

Behavior:

  • Creates a new dictionary copy of the current experiments
  • No network calls - purely returns cached data
  • Data source: experiment map populated from:
    • Initial load from local storage (on startup)
    • Updates from successful API responses (refreshExperiments/fetchExperiments)
  • Returns empty dictionary if no experiments have been loaded yet

Example:

let experiments = try Ascend.getPlugin(AscendExperiments.self)
let variants = experiments.getExperimentVariants()
for (experimentKey, variant) in variants {
print("\(experimentKey): \(variant.variantName)")
}

Persists experiment data to local storage and updates the in-memory cache

Parameters:

  • experiments: [String: Experiment]? containing experiment data to persist (nil to clear all)

Behavior:

  • Persists the experiments data to local storage via AscendStorage
  • Updates the in-memory experiment map with the new data
  • No network calls - purely local storage operation
  • Used for manually setting experiment data (e.g., from external sources or testing)

Return/Fallback Order:

  • No return value - This is a void method
  • No fallback mechanism - If persistence fails, the error is logged but not propagated
  • Immediate effect - Data is immediately available in memory after calling this method
  • Storage failure handling - If storage write fails, the in-memory map is still updated, so experiments remain available for the current session

Example:

let experiments = try Ascend.getPlugin(AscendExperiments.self)
// Set experiments
let testExperiments: [String: Experiment] = [
"test_key": Experiment(
experimentId: "exp-123",
userIdentifierType: "user_id",
status: "active",
variables: .dictionary(["color": .string("red")]),
experimentKey: "test_key",
variantName: "variant_a"
)
]
experiments.setExperimentsToStorage(testExperiments)
// Clear all experiments
experiments.setExperimentsToStorage(nil)

Retrieves experiment data from local storage (disk)

Parameters:

  • None

Returns: [String: Experiment]? containing persisted experiment data, or nil if not found

Behavior:

  • Returns a dictionary containing persisted experiment data
  • Reads from disk storage using the ascend_experiments.json file
  • No network calls - purely local storage operation
  • Used to retrieve previously saved experiment data
  • Supports both ExperimentSnapshot format (new) and raw dictionary format (legacy)

Return/Fallback Order:

  • Returns: [String: Experiment]? - the persisted experiment data
  • Fallback mechanism:
    • If file doesn’t exist, returns nil
    • If JSON deserialization fails, returns nil
    • No exception thrown - gracefully handles storage issues
  • Data source priority: Only reads from local disk storage, does not check in-memory cache

Example:

let experiments = try Ascend.getPlugin(AscendExperiments.self)
if let storedExperiments = experiments.getExperimentsFromStorage() {
print("Loaded \(storedExperiments.count) experiments from storage")
for (key, experiment) in storedExperiments {
print("\(key): \(experiment.variantName)")
}
} else {
print("No experiments found in storage")
}

Returns all currently loaded experiment variants as a JSON string

Parameters:

  • None

Returns: String? containing JSON representation of all experiment variants, or nil if encoding fails

Behavior:

  • Gets all experiment variants using getExperimentVariants()
  • Encodes the variants dictionary to JSON string
  • Returns nil if JSON encoding fails

Example:

let experiments = try Ascend.getPlugin(AscendExperiments.self)
if let jsonString = experiments.getExperimentVariantsJSON() {
print("Variants JSON: \(jsonString)")
}

Returns the default experiment values that were configured at initialization

Parameters:

  • None

Returns: [String: ExperimentVariable] - Dictionary of default experiment values keyed by API path

Behavior:

  • Returns the default experiments map that was provided during configuration
  • No network calls - purely returns configured defaults
  • Used to retrieve the default values that were set at initialization

Example:

let experiments = try Ascend.getPlugin(AscendExperiments.self)
let defaults = experiments.getDefaultExperimentValues()
for (key, value) in defaults {
print("Default for \(key): \(value)")
}

Loads experiments data asynchronously from disk storage with snapshot information

Parameters:

  • completion: Completion handler with (ExperimentSnapshot?, Error?) parameters

Behavior:

  • Returns ExperimentSnapshot containing:
    • timestamp: Timestamp when the snapshot was taken
    • data: Dictionary of experiments keyed by their API path
  • Reads from disk storage using the ascend_experiments.json file
  • Supports both ExperimentSnapshot format (new) and raw dictionary format (legacy)
  • For legacy format, uses file modification date as timestamp
  • No network calls - purely local storage operation

On Success:

  • Calls completion handler with ExperimentSnapshot containing persisted data (on main thread)

On Error:

  • Calls completion handler with nil snapshot and error (on main thread)

Example:

let experiments = try Ascend.getPlugin(AscendExperiments.self)
experiments.loadExperimentsData { snapshot, error in
if let error = error {
print("Error loading experiments: \(error)")
} else if let snapshot = snapshot {
print("Loaded snapshot with \(snapshot.count) experiments at timestamp: \(snapshot.timestamp)")
}
}

Clears all experiments data from memory and storage

Parameters:

  • None

Returns: Void

Behavior:

  • Clears currentExperiments map
  • Clears defaultExperiments map
  • Clears access map (session-scoped cache)
  • Persists empty state to local storage
  • No network calls - purely local operation
  • Used when user logs out or when you want to reset all experiment data

Example:

let experiments = try Ascend.getPlugin(AscendExperiments.self)
experiments.clearAllExperimentsData()
print("All experiments data cleared")

Coming soon…