User Consent¶
Part of the Human Scoring use case.
The SDK records how the user interacts with your app, so by default it records nothing until the user agrees. The SDK ships a ready-made consent alert for SwiftUI and UIKit, and you can replace it with your own UI without losing the guarantee.
When to use it¶
- Always, unless your app already obtains consent before creating the
DeaSdk— in that case, setrequireConsent: false - To change the wording of the alert, or translate it
- To let the user withdraw consent from a settings screen
Prerequisites¶
- The SDK is installed and started. See the Quick Start.
- The SwiftUI alert needs iOS 15 or later. The UIKit alert works from iOS 13.
Usage¶
Show the built-in alert (UIKit)¶
import DeaSDK
import UIKit
class HomeViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
Dea.sdk?.requestConsent(from: self) { agreed in
print("DEA consent: \(agreed)")
}
}
}
- The answer is stored on the device. Once the user has answered, later calls call
completionwith the stored answer straight away and show nothing, so it is safe to call on every launch. - The alert has two buttons, both answers. It cannot be dismissed by tapping outside.
Show the built-in alert (SwiftUI)¶
import DeaBase
import DeaSDK
import SwiftUI
struct HomeView: View {
@State private var askingConsent = false
var body: some View {
let content = Text("Home")
.onAppear {
if let dea = Dea.sdk, !dea.consent.isAnswered {
askingConsent = true
}
}
if let dea = Dea.sdk {
content.deaConsent(dea.consent, asking: $askingConsent) { agreed in
print("DEA consent: \(agreed)")
}
} else {
content
}
}
}
The deaConsent modifier shows the alert whenever asking becomes true; it does not check the
stored answer itself. Set asking only when consent.isAnswered is false, as above, or the user
is asked on every launch.
Change the wording¶
import DeaSDK
let copy = ConsentCopy(
title: "Help us keep bots out",
body: "We measure how you interact with the app to tell people apart from bots.",
recorded: ["Where you touch, and how hard", "How the phone moves in your hand"],
notRecorded: ["What you type", "What's on your screen"],
closing: "You can change this at any time in Settings.",
accept: "Allow",
decline: "Not now"
)
// UIKit
Dea.sdk?.requestConsent(from: self, copy: copy) { _ in }
// SwiftUI
// content.deaConsent(dea.consent, asking: $askingConsent, copy: copy) { _ in }
Pass an empty array to recorded or notRecorded to hide that section. Make sure the lists stay
true for your app.
Use your own UI¶
Draw your own screen or onboarding step, then record the answer:
import DeaSDK
Dea.sdk?.setConsent(true) // the user agreed
Dea.sdk?.setConsent(false) // the user declined
Recording starts or stops as soon as setConsent returns.
Read the current answer¶
import DeaBase
import DeaSDK
if let consent = Dea.sdk?.consent {
print(consent.isAnswered) // false until the user has answered
print(consent.isGranted) // true only if the user agreed
print(consent.decision) // unknown, granted or denied
}
Be notified when the answer changes¶
import DeaBase
import DeaSDK
let stopListening = Dea.sdk?.consent.onChange { decision in
print("DEA consent is now \(decision)")
}
// Later, to stop being notified:
stopListening?()
Withdraw consent¶
Recording stops immediately. The session is kept, so if the user agrees again, recording continues in the same session.
Ask again¶
forget() clears the stored answer, so the next requestConsent call (or your isAnswered
check) asks again — for example when a different account signs in on the same device. Unlike
declining, it is not an answer.
Shared devices¶
When a different person may use the device each session (a kiosk, a test device), do not store the answer:
// UIKit
Dea.sdk?.requestConsent(from: self, remember: false) { _ in }
// SwiftUI
// content.deaConsent(dea.consent, asking: $askingConsent, remember: false) { _ in }
// Your own UI
Dea.sdk?.setConsent(true, remember: false)
With remember: false the UIKit alert is shown on every call and the answer is kept for this run
only.
Examples¶
A settings switch (SwiftUI)¶
import DeaBase
import DeaSDK
import SwiftUI
struct DeaConsentToggle: View {
@State private var granted = Dea.sdk?.consent.isGranted ?? false
var body: some View {
Toggle("Bot protection", isOn: $granted)
.disabled(Dea.sdk == nil)
.onChange(of: granted) { value in
Dea.sdk?.setConsent(value)
}
}
}
A settings switch (UIKit)¶
import DeaBase
import DeaSDK
import UIKit
class PrivacySettingsViewController: UIViewController {
private let toggle = UISwitch()
override func viewDidLoad() {
super.viewDidLoad()
toggle.isOn = Dea.sdk?.consent.isGranted ?? false
toggle.isEnabled = Dea.sdk != nil
toggle.addTarget(self, action: #selector(toggled), for: .valueChanged)
view.addSubview(toggle)
}
@objc private func toggled() {
Dea.sdk?.setConsent(toggle.isOn)
}
}
API¶
| Member | Returns | Description |
|---|---|---|
DeaSdk.requestConsent(from:copy:remember:completion:) |
Void |
UIKit. Shows the alert if needed and calls completion with the answer |
View.deaConsent(_:asking:copy:remember:onAnswer:) |
some View |
SwiftUI, iOS 15+. Shows the alert while asking is true and records the answer |
DeaSdk.setConsent(_:remember:) |
Void |
Records the answer |
DeaSdk.consent |
Consent |
The current answer |
Consent.isAnswered |
Bool |
Whether the user has answered |
Consent.isGranted |
Bool |
Whether the user agreed |
Consent.decision |
ConsentDecision |
.unknown, .granted or .denied |
Consent.forget() |
Void |
Clears the stored answer |
Consent.onChange(_:) |
() -> Void |
Calls the listener when the answer changes; call the returned closure to stop |
Related¶
- Options:
requireConsent - Options:
consent— keep the answer in your own storage - Sensitive Screens
- API Reference