Skip to content

Options

Pass options once, as a DeaSdkOptions value, when you create the DeaSdk. They are read when the instance is created and cannot be changed afterwards; to use different options, dispose() the instance and create a new one.

import DeaBase
import DeaSDK

let dea = DeaSdk(
    options: DeaSdkOptions(
        appId: "YOUR_APP_ID",
        requireConsent: true,
        consent: Consent(store: DefaultsConsentStore()),
        appKey: "YOUR_APP_KEY",
        modelUpdates: true,
        events: CaptureEvent.pointerKinds,
        motionRate: 50
    )
)
dea.start()

Every option except appId has a default, so name only the ones you change. Swift takes the arguments in the order the initializer declares them: appId, requireConsent, consent, appKey, registryAppId, onLog, modelDirectory, modelUpdates, modelTimeout, events, idleMotionMs, motionRate, touchMarginMs.

import DeaBase is only needed when you name Consent, a consent store or CaptureEvent yourself.

Core options

appId

Type Default Required
String — Yes

The appId DEA issued for this iOS app. See Accounts and keys. The addresses the SDK sends requests to are built in: no option changes them.

requireConsent

Type Default Required
Bool true No

When true, nothing is recorded until the user has agreed. See User Consent.

Set it to false only when consent is already established outside the SDK — for example, your app asks during onboarding and creates the DeaSdk only after the user agrees.

Type Default Required
Consent? nil — the answer is stored in UserDefaults.standard No

Where the user's consent answer is kept. Leave it nil unless your app already keeps consent somewhere else and wants the SDK to read and write it there. Pass a Consent built over your own ConsentStore:

import DeaBase
import DeaSDK

final class MyConsentStore: ConsentStore {
    func read() -> ConsentDecision {
        switch MyPrivacySettings.shared.behaviourMeasurement {
        case .some(true): return .granted
        case .some(false): return .denied
        case .none: return .unknown
        }
    }

    func write(_ decision: ConsentDecision) {
        switch decision {
        case .granted: MyPrivacySettings.shared.behaviourMeasurement = true
        case .denied: MyPrivacySettings.shared.behaviourMeasurement = false
        case .unknown: MyPrivacySettings.shared.behaviourMeasurement = nil
        }
    }
}

let dea = DeaSdk(
    options: DeaSdkOptions(
        appId: "YOUR_APP_ID",
        consent: Consent(store: MyConsentStore()),
        appKey: "YOUR_APP_KEY"
    )
)

The store is read once, when the Consent is created. Replace MyPrivacySettings with your own settings storage.

Store Keeps the answer
DefaultsConsentStore() In UserDefaults.standard, across launches (the default)
MemoryConsentStore() For this run only. The user is asked again on every launch

onLog

Type Default Required
((LogEntry) -> Void)? nil No

Called with each log entry the SDK build carries. The production build of the iOS SDK carries no log, so onLog is never called there.

Capture options

events

Type Default Required
[CaptureEvent] CaptureEvent.pointerKinds No

The input kinds to capture. Capturing fewer kinds reduces work but also reduces the evidence the score is built on.

Value Captures
.pointerDown A finger or stylus touches the screen
.pointerMove A touch moves, and a pointer hovers
.pointerUp A touch ends
.pointerCancel The system cancels a touch
.wheel Trackpad and mouse scrolling
.keyDown A key press your app reports with captureKey
.keyUp A key release your app reports with captureKey

CaptureEvent.pointerKinds is the first five. Key kinds are not in the default list and are never captured automatically. Add .keyDown only if your app reports typing — see Report typing. Without it, captureKey does nothing.

import DeaBase
import DeaSDK

let dea = DeaSdk(
    options: DeaSdkOptions(
        appId: "YOUR_APP_ID",
        appKey: "YOUR_APP_KEY",
        events: CaptureEvent.pointerKinds + [.keyDown]
    )
)

Scrolling, hover, and mouse or trackpad pointers are captured but do not add to the score on iOS: the score is built from touches and stylus contacts, device motion, and the key presses your app reports.

motionRate

Type Default Required
Int (Hz) 50 No

The motion sensor rate to request. Values below 25 are raised to 25. sessionInfo.device.sensorRate reports this rate once the first motion reading has arrived, and 0 until then — for the whole run on the simulator or on a device without motion sensors.

idleMotionMs

Type Default Required
Int (ms) 3000 No

When no one is touching the screen, motion data is kept at a reduced rate — one reading every idleMotionMs — until the next touch. 0 keeps every reading.

touchMarginMs

Type Default Required
Int (ms) 200 No

Motion data is kept at the full rate for this long before and after each touch, even while idle.

To keep a screen out of the recording, use pause().

Attestation options

App Attest is used automatically when the App Attest capability is added to your app — see Attest.

appKey

Type Default Required
String? nil Yes, for Attest

The appKey DEA issued with your appId. The SDK sends it in the X-App-Key header when it registers the device key. Leading and trailing spaces are removed, and an empty string counts as no key.

Without it, attest() and renewAttestation() answer .unsupported without contacting DEA, and the result's detail says that no appKey was given. Reading the classification does not need it. DeaSdk.appKey reads back the key the SDK sends.

registryAppId

Type Default Required
String? nil No

The appId the SDK writes inside the proofs it signs, which DEA accepts only when it names the app behind appKey. Set it to your appId. Left nil, proofs carry a built-in development id instead. Attest and getClassification() do not read it; the proof calls on the Ads page do.

Model options

The SDK scores with a model built into it. With modelUpdates on, it also asks DEA's model server whether a newer model is published: every time a DeaSdk is created, and when the app returns to the foreground if a day has passed since the last check that got an answer. It downloads a model only when it is newer than the one running, and the scoring engine checks the file before using it. A new model is used at once, even in the middle of a session, and is kept on the device for the next launch. Checks run in the background: nothing waits for them, and they never throw.

DeaSdk.modelInfo says which model is scoring — see the API Reference.

modelUpdates

Type Default Required
Bool true No

Set it to false to stop the checks. Any downloaded model is deleted when the DeaSdk is created, and the SDK scores with the built-in model.

modelDirectory

Type Default Required
URL? nil — the app's Application Support directory No

Where downloaded models are kept; the SDK creates dea/models inside it. If that folder cannot be created, the SDK checks for no updates and scores with the built-in model.

modelTimeout

Type Default Required
TimeInterval 30 seconds No

How long one model request may take before it is abandoned.

Reserved

DeaSdkOptions has five more parameters, reserved for DEA's own tooling and tests. Leave them at their defaults:

Parameter What it does
integrations Ignored with a production appId
modelUrlOverride Ignored with a production appId
openCore Replaces the scoring engine
keystore Makes the device key or App Attest refuse, to test those failures
urlProtocolClasses Puts URLProtocol classes in front of every request the SDK makes