Record consent in a mobile app
Use the iOS or Android SDK to fetch the form, show your own consent screen, record the answer and gate your app's features on it.
The iOS and Android SDKs record consent from native apps as the same evidence the website produces. They do not draw a banner. Your app shows its own consent screen from the form the server sends, and the SDK records the answer and keeps it on the device.
Before you start#
- A key that lists the app. Under Allowed origins, add
app:followed by the bundle id (iOS) or the application id (Android), such asapp:in.example.kalpa. A key cannot be edited afterwards. - A region rule that sends your users to a published form.
- The SDK added to your project. See iOS SDK or Android SDK.
A test key answers any app. A live key answers only the apps on its list, so an unlisted app gets 401.
Ask and record#
-
Create one client with your publishable key and keep it for the life of the app.
iOSSwift import PiedapConsent let consent = try PiedapConsent( apiUrl: "https://console.dpconsent.com/consent", publishableKey: "pk_…", applicationId: Bundle.main.bundleIdentifier!, store: UserDefaultsConsentStore() )Androidjava import com.piedap.consent.PiedapConsent; PiedapConsent consent = PiedapConsent.builder() .apiUrl("https://console.dpconsent.com/consent") .publishableKey("pk_…") .applicationId(context.getPackageName()) .store(new PreferencesStore(context)) .build(); -
Fetch the form in the user's language.
iOSSwift let locale = Locale.preferredLanguages.first ?? "en" let form = try await consent.loadForm(locale: locale)Androidjava // Network calls block. Run them off the main thread. String locale = Locale.getDefault().toLanguageTag(); ConsentForm form = consent.loadForm(locale, null); -
Show your consent screen when
shouldAskistrue.iOSSwift if consent.shouldAsk(form) { presentConsentScreen(form) }Androidjava if (consent.shouldAsk(form)) { presentConsentScreen(form); } -
On the screen, show the form's title and body, then every purpose with its name, its description and a switch.
-
Record the answer with the call that matches the button the user pressed.
iOSSwift try await consent.acceptAll(form) try await consent.rejectAll(form) try await consent.savePreferences( form, choices: ["analytics": true, "marketing": false] )Androidjava consent.acceptAll(form); consent.rejectAll(form); Map<String, Boolean> choices = new HashMap<>(); choices.put("analytics", true); choices.put("marketing", false); consent.savePreferences(form, choices); -
Gate your own SDKs on
granted.iOSSwift if consent.granted("analytics") { Analytics.enable() }Androidjava if (consent.granted("analytics")) { analytics.enable(); }
The first answer creates a record, kept under a random id made for this install with the type DEVICE_ID. consent.consentId on iOS, or consent.consentId() on Android, returns its id. With a test key the record shows a Test badge under Records in the console.
Three rules for the screen and the store:
- Start each switch from
alwaysOn || defaultGranted, and disable the switch of an always-on purpose. - Offer "accept all" and "reject all" with equal weight, and a way to save a custom choice.
- Give the client a store that lasts. Without one, the SDK forgets everything when the app exits. iOS has
UserDefaultsConsentStorebuilt in. On Android, add the class below.
The Android store class
import android.content.Context;
import android.content.SharedPreferences;
import com.piedap.consent.ConsentStore;
final class PreferencesStore implements ConsentStore {
private final SharedPreferences preferences;
PreferencesStore(Context context) {
preferences = context.getSharedPreferences(
"piedap_consent", Context.MODE_PRIVATE);
}
@Override public String get(String key) {
return preferences.getString(key, null);
}
@Override public void put(String key, String value) {
preferences.edit().putString(key, value).apply();
}
@Override public void remove(String key) {
preferences.edit().remove(key).apply();
}
}Record under a signed-in user#
Your server computes an identity proof and sends it to the app with the session. See Record consent for signed-in visitors. The app passes it on.
try consent.identify(
subjectId: session.userId,
subjectType: .userId,
proof: session.consentProof
)
consent.clearIdentity() // on sign-outconsent.identify(session.userId, "USER_ID", session.consentProof);
consent.clearIdentity(); // on sign-outThe identity is kept in memory only, so call identify after sign-in on every launch. It applies to records created afterwards.
Limits to plan for#
- Only a publishable key belongs in an app. Both SDKs refuse a key that starts with
sk_before they make any request. - There is no offline queue and no retry. If a save fails, the call throws and the answer is not stored. Keep the choice on screen and let the user try again.
- The SDKs do not send linked identifiers. Link an email address or phone number from your server with
linkIdentifiers. - The SDKs answer per purpose only, not partner by partner.