> For the complete documentation index, see [llms.txt](https://docs.amply.tools/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.amply.tools/reference/sdk-ios.md).

# iOS SDK

Public API surface for the Amply iOS SDK. Import the `AmplySDK` framework.

## At a glance

| Group              | Method                                                                                                                                                    |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Initialization     | `Amply(config:)`, `AmplyConfig(appId:apiKeyPublic:apiKeySecret:defaultConfig:configBaseUrl:backendBaseUrl:)`                                              |
| Event tracking     | `track(_:properties:)`                                                                                                                                    |
| User attributes    | `setUserId(_:)`, `setCustomProperty(_:value:)`, `setCustomProperties(_:)`, `getCustomProperty(_:)`, `removeCustomProperty(_:)`, `clearCustomProperties()` |
| Deeplinks          | `registerDeepLinkListener(_:)`                                                                                                                            |
| System events      | `setSystemEventsListener(_:)`                                                                                                                             |
| Session (iOS-only) | `pauseSession()`, `resumeSession()`, `stopSession()`                                                                                                      |
| Data inspection    | `getRecentEvents(limit:)`, `getDataSetSnapshot(type:)`                                                                                                    |
| Logging            | `setLogLevel(_:)`, `getLogLevel()`, `setLogListener(_:)`                                                                                                  |

## Initialization

### `Amply(config: AmplyConfig)`

Construct the SDK. Construction **is** initialization — there is no separate `initialize()` call. The init block creates internal platform components, starts the first session, and delivers any system events emitted during startup to a listener you set later.

Parameters:

| Name     | Type          | Required | Description                                 |
| -------- | ------------- | -------- | ------------------------------------------- |
| `config` | `AmplyConfig` | yes      | Credentials and optional network overrides. |

Retain the returned instance for the lifetime of the app. Creating a second instance is not supported.

### `AmplyConfig`

Credential and network configuration object.

```swift
let config = AmplyConfig(
    appId: "your.app.id",
    apiKeyPublic: "your-public-key",
    apiKeySecret: "your-secret-key"
)
```

Parameters:

| Name             | Type      | Required | Description                                                                 |
| ---------------- | --------- | -------- | --------------------------------------------------------------------------- |
| `appId`          | `String`  | yes      | Application identifier issued in the Amply dashboard.                       |
| `apiKeyPublic`   | `String`  | yes      | Public API key.                                                             |
| `apiKeySecret`   | `String`  | yes      | Secret API key. Keep it out of source control.                              |
| `defaultConfig`  | `String?` | no       | JSON string of a fallback configuration used until the remote config loads. |
| `configBaseUrl`  | `String?` | no       | Override for the configuration service base URL.                            |
| `backendBaseUrl` | `String?` | no       | Override for the events backend base URL.                                   |

## Event tracking

### `track(event: String, properties: [String: Any] = [:])`

Record a custom event.

Parameters:

| Name         | Type            | Required | Description                                        |
| ------------ | --------------- | -------- | -------------------------------------------------- |
| `event`      | `String`        | yes      | Event name.                                        |
| `properties` | `[String: Any]` | no       | Event properties. Defaults to an empty dictionary. |

Returns `Void`. Events are buffered locally and flushed by the SDK; no network call is tied to this call site.

## Gating

Gate a user-facing step on a campaign's outcome — for example, a rewarded ad before an export. See [Gating actions](/developer-guide/gating-actions.md) for the full flow.

### `trackGated(event: String, properties: [String: Any] = [:]) async -> GateDecision`

Track an event and **wait** for any gating campaign on it to resolve, then return the decision. If no gate applies, returns `.proceed(reason: .failOpen)` immediately. Never throws except on caller cancellation.

| Name         | Type            | Required | Description                     |
| ------------ | --------------- | -------- | ------------------------------- |
| `event`      | `String`        | yes      | Event name a campaign may gate. |
| `properties` | `[String: Any]` | no       | Event properties.               |

Returns a `GateDecision`. Call from a Swift `async` context.

### `registerGate(baseUrl: String, presenter: CampaignPresenter, onAbort: AbortPolicy = .cancel, timeoutMs: Int64 = 60000)`

Register the single gate presenter once at startup. The SDK calls the presenter when a gated campaign needs to show UI, and calls its `dismiss()` if the gate is abandoned. Hold a strong reference to the presenter.

| Name        | Type                | Required | Description                                          |
| ----------- | ------------------- | -------- | ---------------------------------------------------- |
| `baseUrl`   | `String`            | yes      | Base URL the gate resolves against.                  |
| `presenter` | `CampaignPresenter` | yes      | Your presenter (see below).                          |
| `onAbort`   | `AbortPolicy`       | no       | What a user dismiss means. Default `.cancel`.        |
| `timeoutMs` | `Int64`             | no       | Fail-open deadline in milliseconds. Default `60000`. |

### `GateDecision`

Sealed type with two cases:

| Case                | Meaning                                                                      |
| ------------------- | ---------------------------------------------------------------------------- |
| `.proceed(reason:)` | Do the next step. `reason` is a `ProceedReason`.                             |
| `.cancelled`        | User deliberately dismissed a `.cancel`-policy gate. Suppress the next step. |

Match with `if case .proceed = decision { … }` or `decision is GateDecision.Cancelled`.

### `ProceedReason`

| Case         | Meaning                                                                    |
| ------------ | -------------------------------------------------------------------------- |
| `.completed` | The campaign's value-exchange was satisfied (e.g. reward earned).          |
| `.failOpen`  | Nothing to wait on, or the gate couldn't run to a decision. Do not reward. |

### `AbortPolicy`

| Case       | Meaning                                                                             |
| ---------- | ----------------------------------------------------------------------------------- |
| `.cancel`  | (default) A dismiss returns `.cancelled` — true gating, for value-exchange actions. |
| `.proceed` | A dismiss returns `.proceed(reason: .failOpen)` — for consent-style flows.          |

### `CampaignPresenter`

```swift
protocol CampaignPresenter {
    func present(params: [String: String], info: [String: Any], resolution: CampaignResolution)
    func dismiss()
}
```

`present` shows the gated UI and reports the result through the `resolution` handle; `dismiss` tears it down without producing a result (the SDK calls it when the gate is abandoned). Both are required.

### `CampaignResolution` / `CampaignResult`

The `resolution` handle passed to `present(...)` reports the outcome exactly once:

```swift
resolution.resolve(result: .completed)    // value-exchange satisfied → gate proceeds (reason .completed)
resolution.resolve(result: .dismissed)    // user backed out → honors the onAbort policy
resolution.resolve(result: .unavailable)  // couldn't run (no fill / error) → fail-open
```

`CampaignResult`: `.completed` / `.dismissed` / `.unavailable`.

## User attributes

### `setUserId(userId: String?)`

Associate subsequent events with a user identifier. Pass `nil` to clear.

| Name     | Type      | Required | Description                                  |
| -------- | --------- | -------- | -------------------------------------------- |
| `userId` | `String?` | yes      | Stable user identifier, or `nil` to log out. |

Returns `Void`. Survives across sessions until changed.

### `setCustomProperty(key: String, value: Any)`

Set one custom property on the current user.

| Name    | Type     | Required | Description                                                                   |
| ------- | -------- | -------- | ----------------------------------------------------------------------------- |
| `key`   | `String` | yes      | Property key.                                                                 |
| `value` | `Any`    | yes      | One of: `String`, `Int`, `Int64`, `Float`, `Double`, `Bool`, `DateTimeValue`. |

Returns `Void`. Use `DateTimeValue(epochMillis:)` to persist a value as a datetime rather than a plain number.

### `setCustomProperties(properties: [String: Any])`

Set multiple custom properties in one call.

| Name         | Type            | Required | Description                      |
| ------------ | --------------- | -------- | -------------------------------- |
| `properties` | `[String: Any]` | yes      | Map of keys to supported values. |

Returns `Void`. Equivalent to calling `setCustomProperty` per entry.

### `getCustomProperty(key: String) async -> Any?`

Read the current value of a custom property.

| Name  | Type     | Required | Description   |
| ----- | -------- | -------- | ------------- |
| `key` | `String` | yes      | Property key. |

Returns `Any?` — the stored value, or `nil` if unset. Call from a Swift `async` context.

### `removeCustomProperty(key: String)`

Delete a single custom property.

| Name  | Type     | Required | Description             |
| ----- | -------- | -------- | ----------------------- |
| `key` | `String` | yes      | Property key to remove. |

Returns `Void`.

### `clearCustomProperties()`

Remove every custom property for the current user. Returns `Void`.

## Deeplinks

### `registerDeepLinkListener(listener: DeepLinkListener)`

Register a handler that receives campaign deep link URLs opened by the SDK.

| Name       | Type               | Required | Description                                           |
| ---------- | ------------------ | -------- | ----------------------------------------------------- |
| `listener` | `DeepLinkListener` | yes      | Handler implementing `onDeepLink(url:info:) -> Bool`. |

Returns `Void`. Multiple listeners can be registered; each is invoked in registration order.

### `DeepLinkListener`

Protocol with a single method:

```swift
protocol DeepLinkListener {
    func onDeepLink(url: String, info: [String: Any]) -> Bool
}
```

Return `true` if your app handled the URL; `false` lets other listeners handle it.

## System events

### `setSystemEventsListener(listener: SystemEventsListener)`

Receive SDK lifecycle events (session start, config fetch, campaign shown).

| Name       | Type                   | Required | Description                                     |
| ---------- | ---------------------- | -------- | ----------------------------------------------- |
| `listener` | `SystemEventsListener` | yes      | Handler with a single `onEvent(event:)` method. |

Returns `Void`. Replaces any previously set listener. Events that fire before the listener is set are queued and delivered synchronously at registration time.

### `SystemEventsListener`

```swift
protocol SystemEventsListener {
    func onEvent(event: EventInterface)
}
```

`EventInterface` exposes `name: String`, `timestamp: Int64`, `properties: [String: Any]`, and `type: EventType` (`Custom` or `.system`).

## Session (iOS-only)

On iOS you drive session boundaries manually from your `UIApplicationDelegate` or `ScenePhase` observer. Android handles this automatically via the activity lifecycle.

### `pauseSession()`

Pause the current session when the app enters the background. Returns `Void`. Call from `applicationDidEnterBackground` or equivalent.

### `resumeSession()`

Resume a paused session or start a new one if the pause exceeded the session timeout. Returns `Void`. Call from `applicationDidBecomeActive` or equivalent.

### `stopSession()`

Finalize and flush the current session. Returns `Void`. Call on app termination.

## Data inspection

### `getRecentEvents(limit: Int32 = 30) async -> [EventInterface]`

Fetch the most recent events tracked in the current install. Intended for in-app debug tools.

| Name    | Type    | Required | Description                                         |
| ------- | ------- | -------- | --------------------------------------------------- |
| `limit` | `Int32` | no       | Maximum number of events to return. Defaults to 30. |

Returns `[EventInterface]` newest-first. Call from a Swift `async` context.

### `getDataSetSnapshot(type: DataSetType) async -> [String: Any]`

Return a snapshot of one dataset the SDK uses for targeting.

| Name   | Type          | Required | Description       |
| ------ | ------------- | -------- | ----------------- |
| `type` | `DataSetType` | yes      | Dataset selector. |

Returns `[String: Any]`. Call from a Swift `async` context.

### `DataSetType`

Sealed type with these variants:

| Variant                                           | Contents                                         |
| ------------------------------------------------- | ------------------------------------------------ |
| `Device`                                          | IDFA, IDFV, model, OS version, locale, timezone. |
| `User`                                            | User ID and identity attributes.                 |
| `Custom`                                          | All custom properties you've set.                |
| `Session`                                         | Current session metadata.                        |
| `TriggeredEvent(countStrategy:params:eventName:)` | Aggregated counts for a specific event.          |
| `Events(data:)`                                   | Counts for a list of event names.                |

## Logging

### `setLogLevel(level: LogLevel)`

Set the SDK log level.

| Name    | Type       | Required | Description                                           |
| ------- | ---------- | -------- | ----------------------------------------------------- |
| `level` | `LogLevel` | yes      | One of `.none`, `.error`, `.warn`, `.info`, `.debug`. |

Returns `Void`. Defaults to `.none`.

### `setLogLevel(level: String?)`

String overload. Accepts `"none"`, `"error"`, `"warn"`, `"info"`, `"debug"` (case-insensitive). Any other value — including `nil` — maps to `.none`. Returns `Void`.

### `getLogLevel() -> LogLevel`

Return the current log level. Takes no parameters.

### `setLogListener(listener: LogListener?)`

Install a handler that receives every SDK log entry above the current level. Pass `nil` to remove the existing listener.

| Name       | Type           | Required | Description                                              |
| ---------- | -------------- | -------- | -------------------------------------------------------- |
| `listener` | `LogListener?` | yes      | Handler implementing `onLog(entry:)`, or `nil` to clear. |

Returns `Void`.

### `LogListener`

```swift
protocol LogListener {
    func onLog(entry: LogEntry)
}
```

`LogEntry` fields: `level: LogLevel`, `category: String`, `message: String`, `timestamp: Int64`, `details: [String: Any]?`.

## Types

### `LogLevel`

Enum: `.none`, `.error`, `.warn`, `.info`, `.debug`. Ordered by verbosity — `.debug` logs everything.

### `DateTimeValue`

```swift
DateTimeValue(epochMillis: Int64)
```

Wrapper used with `setCustomProperty` to mark a value as a datetime rather than a number.

### `EventInterface`

| Field        | Type            | Description             |
| ------------ | --------------- | ----------------------- |
| `name`       | `String`        | Event name.             |
| `timestamp`  | `Int64`         | UTC epoch milliseconds. |
| `properties` | `[String: Any]` | Event properties.       |
| `type`       | `EventType`     | `Custom` or `.system`.  |

### System event names

Well-known values on `EventInterface.name` when `type == .system`:

| Name                    | When it fires                                                                                     |
| ----------------------- | ------------------------------------------------------------------------------------------------- |
| `SdkInitialized`        | SDK finished initialization.                                                                      |
| `ConfigFetchStarted`    | Remote configuration fetch began.                                                                 |
| `ConfigFetchFinished`   | Remote configuration fetch completed.                                                             |
| `SessionStarted`        | Session started. `properties.type` is `"cold"` or `"warm"`.                                       |
| `SessionFinished`       | Session ended.                                                                                    |
| `CampaignShown`         | Campaign impression recorded.                                                                     |
| `EventTriggered`        | A custom event matched a campaign trigger.                                                        |
| `CustomPropertyChanged` | A custom property was set, updated, removed, or cleared. Usable as a campaign trigger.            |
| `CampaignResolved`      | A presented (blocking) campaign action resolved or was skipped (0.5.0+). Recorded for stats only. |

## Related

* [Android SDK reference](/reference/sdk-android.md) — the Android native platform surface.
* [React Native SDK reference](/reference/sdk-react-native.md) — TypeScript surface for RN apps.
