For the complete documentation index, see llms.txt. This page is also available as Markdown.

iOS — Reference

Every method and event exposed by the iOS SDK. Setup and the recommended integration order live in Setup.

iOS SDK — IosCMPApi

The primary interface for iOS publishers. All methods delegate to the IosCMPManager singleton.

import SirDataCMP, then call through IosCMPApi.shared. The signatures below are written as Swift sees them in the framework's exported header: Kotlin Int is Int32, Long is Int64, and a Kotlin suspend function is both async throws and a completionHandler: variant. The only error those variants pass on is a Kotlin CancellationException — in the next release, acceptAll, rejectAll, saveConsent and submitConsent also pass on the IllegalStateException raised before initialize.

Call initialize exactly once, on the main thread, before any other SDK call. Kotlin exceptions are not converted to Swift errors: a misuse that throws in Kotlin terminates the app. That is the case of a second initialize (without shutdown() in between), and of any of these calls before initialize: getConsentState(), getConsentData(), getConsentUpdates(), getLastTcStringError(), discardPendingChanges(), getGoogleConsentState(), getLastForwardedConsentState(), getRegisteredAdapters(), acceptAll(), rejectAll(), saveConsent(), submitConsent(userAction:), and creating a ConsentView. This is 2.0.0 behaviour. In the next release (unreleased) none of these terminates the app: the getters return a neutral value, the four submissions throw a Swift error, a second initialize is ignored and logged, and ConsentView shows a message with a Close button.

Initialization

Method
Signature
Description

initialize

func initialize(partnerId: Int32, configId: String)

Initialize with partner credentials. Main thread only. Writes IABTCF_CmpSdkID, IABTCF_CmpSdkVersion and IABTCF_PolicyVersion to NSUserDefaults immediately, then loads the publisher configuration asynchronously; the keys written once it has loaded, before any choice, are listed in Setup. A second call without shutdown() terminates the app in 2.0.0; the next release ignores it and logs it.

initialize

func initialize(config: IosCMPConfig)

Same, with a full configuration object — see IosCMPConfig below.

isInitialized

func isInitialized() -> Bool

Returns true once initialize has been called, before the configuration has loaded.

getInitError

func getInitError() -> String?

nil while the configuration loads and after it loaded; the error message once a load has failed (unknown config ID, network down…). Cleared by the next initialize. In 2.0.0 it is set a moment after getConsentState() turns READY; the next release sets it before, so it is there when awaitConsentDisplayDecision() returns. The failure is not logged on iOS — see Logging.

shutdown

func shutdown()

Clears in-memory state and cancels a configuration load in flight. Stored consent stays in NSUserDefaults. Main thread only.

Method
Signature
Description

notifyBannerShown

func notifyBannerShown()

Fires cmpuishown event. Call it each time you present ConsentView, just before presenting it.

notifyBannerClosed

func notifyBannerClosed()

Fires cmpuiclosed to TCF and GPP listeners. ConsentView calls it itself when it finishes or is dismissed: call it only for a consent UI of your own.

All five need an initialized SDK.

Method
Signature
Returns
Description

acceptAll

func acceptAll() async throws -> ConsentResult

ConsentResult

Accept all purposes, vendors, and features.

rejectAll

func rejectAll() async throws -> ConsentResult

ConsentResult

Reject all purposes, vendors, and features.

saveConsent

func saveConsent() async throws -> ConsentResult

ConsentResult

Save current selections.

submitConsent

func submitConsent(userAction: UserActionResponse) async throws -> ConsentResult

ConsentResult

Records the current selections and reports them with the given answer.

discardPendingChanges

func discardPendingChanges()

—

Discards the selections changed since the last recorded choice. Call it right before submitting when the user declines to apply pending changes, as the "do not apply" button of the apply-choices banner does.

Each recorded choice fires useractioncomplete to TCF and GPP listeners and forwards the Google consent signals to the consent adapters.

Method
Signature
Returns

getTcString

func getTcString() -> String

IAB TC String

getGppString

func getGppString() -> String

GPP String

getUspString

func getUspString() -> String

USP String — empty when no US choice has been recorded

getAddtlConsent

func getAddtlConsent() -> String

Additional Consent String

isGdprApplies

func isGdprApplies() -> Bool

GDPR applicability — context.gdprApplies from the API once loaded, device geo before

isCcpaApplies

func isCcpaApplies() -> Bool

US Privacy applicability — context.ccpaApplies from the API once the configuration has loaded (from the visitor's country and US state), device geo before

shouldCollectConsent

func shouldCollectConsent() -> Bool

Web checkConsent() cascade, answered immediately (provisional before the config lands)

getConsentDisplayDecision

func getConsentDisplayDecision() -> ConsentDisplayDecision

shouldDisplay + workflow + reason, also immediate — see Display decision

awaitConsentDisplayDecision

func awaitConsentDisplayDecision() async throws -> ConsentDisplayDecision

Waits for the config, then decides. Swift: try await

awaitConsentDisplayDecision

func awaitConsentDisplayDecision(timeoutMillis: Int64) async throws -> ConsentDisplayDecision

Same, bounded

recordPrompt / recordAskLater

func recordPrompt() / func recordAskLater()

Restart the cappingInDays window (only for a re-open the user asked for; ConsentView with .manualDisplay already does it) / record an explicit "ask me later", which hides the banner for one hour, a fixed duration, and records no consent. Both do nothing before initialize

getConsentState

func getConsentState() -> any Kotlinx_coroutines_coreStateFlow

Observable state flow — observe it with ConsentStateWatcher. Needs an initialized SDK

getConsentData

func getConsentData() -> ConsentData

Full consent data. Needs an initialized SDK

getConsentUpdates

func getConsentUpdates() -> any Kotlinx_coroutines_coreStateFlow

Counter bumped on every change to the selections — each toggle in the consent UI, before the user saves, as well as each recorded choice. A US choice (the US screen, or setCcpaOptOut) does not bump it: re-read getUspString() and getGppString() when the consent UI closes. A Kotlin flow cannot be collected from Swift: observe it with UpdateCounterWatcher. Needs an initialized SDK

getLastTcStringError

func getLastTcStringError() -> String?

Outcome of the last server archive of a recorded choice (/consent-string): nil when it succeeded or none has run, otherwise a message starting with /consent-string. Set in the background after submitConsent returns. Despite its name, it does not report on the TC string, which is encoded on the device. Needs an initialized SDK

getPurposeConsents

func getPurposeConsents() -> String

Purpose consents bit field

getVendorConsents

func getVendorConsents() -> String

Vendor consents bit field

hasPurposeConsent

func hasPurposeConsent(purposeId: Int32) -> Bool

Check purpose consent

hasVendorConsent

func hasVendorConsent(vendorId: Int32) -> Bool

Check vendor consent

All three need an initialized SDK.

Method
Signature
Returns

getGoogleConsentState

func getGoogleConsentState() -> GoogleConsentState

The Google consent signals computed from the current selections: what the adapters would receive

getLastForwardedConsentState

func getLastForwardedConsentState() -> GoogleConsentState?

What was actually forwarded to the adapters, or nil when no choice has been recorded since initialize

getRegisteredAdapters

func getRegisteredAdapters() -> [String]

The adapters whose SDK is linked into the app: "Firebase Analytics", "AppsFlyer", "Adjust", "Branch"

GoogleConsentState carries adStorageGranted, analyticsStorageGranted, adUserDataGranted, adPersonalizationGranted, personalizationStorageGranted, functionalityStorageGranted, securityStorageGranted, isSubjectToGDPR, hasConsentForDataUsage and adSignalsFromTcf — true when the configuration leaves the three ad signals to Google, in which case the Firebase adapter does not send them. See Sharing consent with vendor SDKs.

Observing changes from Swift

The two Kotlin flows above are observed through watchers. Each calls its block on the main thread; keep the watcher alive while you need it, and call close() when done. Calling watch again replaces the previous block.

Watcher
Signature
Description

UpdateCounterWatcher

init(flow: any Kotlinx_coroutines_coreStateFlow), func watch(block: @escaping (KotlinLong) -> Void), func close()

For getConsentUpdates(). Skips the current value: the block runs on the next change, not at startup. A burst of changes, such as one tap on a stack, is batched.

ConsentStateWatcher

init(flow: any Kotlinx_coroutines_coreStateFlow), func watch(block: @escaping (ConsentState) -> Void), func close()

For getConsentState(). Delivers the current state, then every change.

IAB API Access

Method
Returns
Description

tcfApi()

TcfApiHandler

IAB TCF CMP API v2

gppApi()

GppApiHandler

GPP API

uspApi()

UspApiHandler

USP/CCPA API

The commands and their data are the same as on Android — see the command tables in Reference — Android. The TCF and GPP handlers call back on the main thread; getUspData calls back synchronously, on the calling thread. Their Swift signatures:

The success flag is a KotlinBoolean: read it with success.boolValue. TCF listener callbacks carry no eventStatus in 2.0.0 — see the in-app command API.

CCPA Opt-Out

Method
Description

setCcpaOptOut(optedOut: Bool)

Records the user's "Do Not Sell" choice: writes IABUSPrivacy_String and, once the SDK is initialized, re-encodes the GPP string (sections 6 and 7). Call it from a control the user operates, never on their behalf. Main thread only. The consent UI's US screen calls it when the user saves. It does not bump the getConsentUpdates() counter

isCcpaOptedOut() -> Bool

Returns opt-out status

Data Management

Method
Description

clearConsent()

Clears ALL persisted consent from NSUserDefaults


IosCMPConfig — iOS Configuration

Field
Swift type
Default

partnerId

Int32

required — your Sirdata partner ID

configId

String

required — your Sirdata config ID

language

String?

nil — accepted, no effect in 2.0.0

apiRoot

String

"https://api.consentframework.com/api/v1/public"

cacheApiRoot

String

"https://choices.consentframework.com/api/v1/public"

consentApiRoot

String

"https://mychoice.consentframework.com/api/v1/public"

debugMode

Bool

false — main-thread violations throw, which terminates the app

gdprDefaultApplies

Bool

true — see below

The defaults are Kotlin defaults, which Swift does not see: the IosCMPConfig initializer takes every argument — partnerId:configId:language:apiRoot:cacheApiRoot:consentApiRoot:debugMode:gdprDefaultApplies:. Use the builder instead.

  • language is accepted but read by nothing in 2.0.0. The UI language is the one pinned in the publisher configuration in the Sirdata Console, if any; otherwise the device language, when the SDK supports it; otherwise the configuration's default language; otherwise English.

  • debugMode only changes the main-thread contract: a call to initialize, shutdown or setCcpaOptOut off the main thread throws instead of being logged — and on iOS that terminates the app. Debug builds only.

  • gdprDefaultApplies is the answer isGdprApplies() gives before the publisher configuration has loaded, when the device reports no region. Once the configuration has loaded, the API decides.

  • The iOS configuration has no theme option: the consent UI takes its colors from the theme configured in the Sirdata Console, in its light or dark version according to the system appearance (the light one when no dark version is configured). It has no certificate pinning option either.

Builder

The builder also has language(language:), which has no effect in 2.0.0.


SwiftUI — ConsentView

import SirDataCMPUI. The consent UI: banner, purposes and partners screens, and the US screen when US Privacy applies. Its initializer, as declared in SirDataCMPUI:

Parameter
Description

onFinish

Called when the user is done with the banner. Dismiss your presentation there.

initialScreen

Screen to open once the CMP is loaded, for example .purposes to open the preferences directly. nil (the default) opens the banner.

workflow

nil (the default) asks the display decision, so a partially answered consent opens in "apply choices" mode. Pass .manualDisplay when re-opening from a settings screen: the banner shows the close cross at the top and a "Reject all" button whatever the refusal type the publisher configured, restarts the cappingInDays window, and is reported as load:revisit.

  • Call IosCMPApi.shared.notifyBannerShown() just before presenting it. ConsentView fires cmpuiclosed itself.

  • Dismissing it without one of its buttons — swiping its sheet down, or pushing another view over it — records nothing: it is reported like the close button that saves nothing, and the banner comes back on the next launch.

  • Creating it before initialize terminates the app in 2.0.0. The next release shows a message with a Close button instead.

  • Known issue in 2.0.0: when the configuration could not be loaded at this launch (offline, for instance), it shows only a loading indicator, with no close control. A .sheet can still be swiped down; with .interactiveDismissDisabled() or in a full-screen presentation, nothing closes it. Present it in those two ways only when IosCMPApi.shared.tcfApi().isCmpLoaded() is true — see Setup. Fixed in the next release: a message and a Close button, and a Close button under the loading indicator after five seconds.

ConsentScreen

Value
Description

.main

The banner

.purposes

The purposes screen

.vendors

The partners screen

.purposeOne

The purpose 1 screen of the cookie wall

.mainMissing, .vendorsMissing

Not entry screens: values recorded in the TC string's consent screen field


Display decision

ConsentDisplayDecision has three properties: shouldDisplay: Bool, workflow: Workflow (pass it to ConsentView) and reason: DisplayReason.

Workflow

Description

.main

The standard banner. Also the workflow of every decision that does not display.

.applyChoices

Returned when the stored choice is missing only partners: the banner asks only about what is left to decide.

.cookiewall

Returned when the configuration enables the cookie wall and the stored choice does not grant purpose 1.

.cookiewallModify

Set by the consent UI itself when the user modifies their choices from the cookie wall. The decision never returns it.

.manualDisplay

Re-opening from a settings screen, passed by the app. The decision never returns it.

DisplayReason

shouldDisplay

Meaning

.gdprNotApplies

false

GDPR does not apply.

.consentRequired

true

Something is left to ask.

.cappingActive

false

A capping window is running on a stored choice that does not grant purpose 1.

.cappingAskLater

false

Nothing is stored, and "ask me later" was recorded less than an hour ago.

.consentOk

false

The stored choice needs nothing more, or a capping window is running on a choice that grants purpose 1.

.configNotLoaded

true or false

Provisional: the configuration had not loaded, so only GDPR applicability and the presence of a stored TC string were evaluated.


Shared Core Types

These types are shared with Android, and shown here in Kotlin, the language they are written in. Swift sees Int fields as Int32, Long as Int64, sets as Set<KotlinInt>, sealed-class cases as nested classes (ConsentResult.Success, ConsentResult.Error) and enum entries in lower camel case (ConsentState.ready, UserActionResponse.askLater).

ConsentResult

InitResult

ConsentState

ConsentData

CoreData

CustomData

PublisherTCData

UserActionResponse

ASK_LATER is reported to Sirdata as an "ask later" answer, but submitConsent still records the current selections, as for any other value. The consent UI never submits it: its "ask me later" button calls recordAskLater(), which records no consent.

SelectorStatus

Mis à jour

Ce contenu vous a-t-il été utile ?