When Consent Changes
Overview
When a user updates their consent choices or interacts with the OT SDK UI, the Application needs to become aware so that it can control the next set of actions like:
- Allowing or restricting processing of 3rd party SDKs based on their categorization
- Passing latest user consent values to 3rd Party SDKs
- Passing the IAB's encoded TC String to 3rd party SDKs
- Passing the IAB's USP String to 3rd Party SDKs
- Routing the User to another location in the App
- Displaying messages to the User of their changes
- Logging updates to internally owned APIs
- etc...
The SDK offers two options to detect user consent:
- Observing Broadcast Events
- Querying for User Consent
The SDK also provides a way to listen for UI interaction events. More detail below: Listening for UI Interaction Events
Recommended Approach:
OneTrust recommends you set up observers and rely on the OT SDK broadcasts as the primary method to action on consent.
Alternative Approach:
If for some reason you are unable to utilize broadcast events to action on consent, the SDK provides a way to rely on UI interaction events and querying for consent. In this case, OneTrust recommends you Query for Consent inside UI Interaction Events to action on consent.
Observing Broadcast Events
Every time the SDK is initialized or the user's consent changes, the OT SDK will broadcast an event for each Category ID and SDK ID and passes the latest consent value. You can use these events and consent values to trigger some action.
Your app can listen to either the categories itself or each individual SDK you want to manage. OneTrust recommends setting up observers on the category level to minimize the amount of observers you have to initialize.
The SDK will broadcast events for always active categories/SDKs as well.
Use Case: Applications needs observers for the SDKs or Categories that require some action to be taken when a user gives/withdraws their consent.
Example: When a user opts out of the "Sale of Personal Data" category, set a privacy or opt out flag in Targeting SDKs in scope so no personalized ads or ads of any kind are shown to the user.
Category IDs
When setting up your observers, you'll want to listen for changes based on the category's ID (OptanonGroupId
).
Note: These
OptanonGroupId
s are friendly variables which can be updated in the OneTrust tenant under Cookie Consent > Categorization > Categories.
Here are the default values as set by OneTrust:
Category Name | Category ID |
---|---|
Strictly Necessary | C0001 |
Performance | C0002 |
Functional | C0003 |
Targeting | C0004 |
Social Media | C0005 |
SDK IDs
When setting up your observers, you'll want to listen for changes based on each SDK's ID. SDK IDs can be found in your tenant under Cookie Categories > SDKs > Your App > Instructions
Notification Object
The notification object returns an integer value and indicates the consent of the user.
- 1 = Consent is given
- 0 = Consent is not given
- -1 = Consent has not been collected (The SDK is not yet initialized OR there are no SDKs associated to this category)
Setting it up
- Create a function that will be called when the observer is triggered. If you are listening for categories, you will need to create a function for each category.
// Swift
@objc func actionConsent_Category_Name(_ notification:Notification){
let consentValue = notification.object as? String
NSLog("Category Consent Value = \(consentValue ?? "false")")
}
@objc func actionConsent_SDK_Name(_ notification:Notification){
let consentValue = notification.object as? String
NSLog("SDK Consent Value = \(consentValue ?? "false")")
}
- Register the observer. Your application will need to register an observer for each category you created an observer function for.
NotificationCenter.default.addObserver(
self,
selector: #selector(actionConsent_Category_Name(_:)),
name: NSNotification.Name(rawValue: "C0003"),
object: nil
)
NotificationCenter.default.addObserver(
self,
selector: #selector(actionConsent_SDK_Name(_:)),
name: NSNotification.Name(rawValue: "SDK ID Value"),
object: nil
)
- Unregister the observer when the view is destroyed.
NotificationCenter.default.removeObserver(NSNotification.Name(rawValue: "C0003"))
NotificationCenter.default.removeObserver(NSNotification.Name(rawValue: "SDK ID Value"))
OTConsentUpdated
The OT SDK will also broadcast a generic event every time a OneTrust UI (banner or preference center) is dismissed.
Use case: Applications need to know when they can query for latest consent for vendors, categories, SDKs, etc. This is useful in cases where you do not or cannot set up multiple observers for each category or SDK.
Event name: OTConsentUpdated
1. Observer Call Back
//observer callback
@objc func returnConsentOTConsentUpdated(_ notification:Notification){
NSLog("OT Consent Updated Notification Fired")
}
2.Registering the observer
//registering the observer
NotificationCenter.default.addObserver(self, selector:
#selector(returnConsentOTConsentUpdated(_:)),
name: Notification.Name("OTConsentUpdated"),
object: nil)
3.Destroying the observer
//destroying the observer
NotificationCenter.default.removeObserver(NSNotification.Name(rawValue: "OTConsentUpdated"))
Querying for Consent
You can query for consent on a category or SDK level.
Querying Consent Status for a Category
Query the current consent status for any of the categories included in your application. This can be used to determine what privacy action is needed at app launch or anytime the consent status is needed without being notified by an event broadcast. Simply pass in the Category ID (eg. C0001) and the method will return the current consent status (integer value).
Value Returned
- 1 = Consent is given
- 0 = Consent is not given
- -1 = Consent has not been collected (The SDK is not initialized or category does not exist OR there are no SDKs associated to this category)
// Swift
OTPublishersHeadlessSDK.shared.getConsentStatus(forCategory: "C0002")
// ObjC
[OTPublishersHeadlessSDK.shared getConsentStatusForCategory:@"C0002"];
Parameters
- forCategory - This is the ID for the categories in scope. It can be found in the OneTrust tenant under Cookie Consent > Categorizations > Categories
Query Consent Status for a Specific SDK
Query the current consent status for any of the SDKs included in your application. This can be used to determine what privacy action is needed at application launch or anytime the consent status is needed without being notified by an event broadcast. Pass in the SDK ID and the method will return the current consent status (integer value).
Value Returned
- 1 = Consent is given
- 0 = Consent is not given
- -1 = Consent has not been collected (The SDK is not initialized or OR there are no SDKs associated to this category)
Tip: SDK IDs can be found in your tenant under Cookie Consent > SDKs > Your App > Instructions
// Swift
OTPublishersHeadlessSDK.shared.getConsentStatus(forSDKId: "2368810c-94da-4f18-ab92-c55c5f74cca9")
// ObjC
[OTPublishersHeadlessSDK.shared getConsentStatusForSDKId:@"2368810c-94da-4f18-ab92-c55c5f74cca9"];
Parameters
- forSDKId - This is the ID for the SDKs assigned to your app. It can be found in the OneTrust tenant under Cookie Categories > SDKs > Your App > Instructions
Query Consent for Vendors
If your app includes a list of vendors such as General Vendors, IAB Vendors or Google Vendors that you need to account for in terms of consent, you query for the status on a vendor level.
Value Returned
getVendorDetails() returns a JSON containing all information regarding a vendor list you specify. Because we're only concerned with the consent status, we'll want to target the consent key. Reference the example code below.
- 2 = Vendor mapped to an always active category (e.g. Strictly Necessary)
- 1 = Consent is given
- 0 = Consent is not given
Parameters
The method takes in two parameters:
- OTVendorListMode - Type of vendor list to retrieve
- General: returns a list of general vendors
- Google: returns a lsit of google vendors
- IAB: returns a list of IAB vendors
- Vendor ID
Tip: Vendor IDs can be found in your tenant under Cookie Consent > Vendors
General Vendor
if let vendorConsent = OTPublishersHeadlessSDK.shared.getVendorDetails(vendorID: "vendorID", for: VendorListMode.general)?["consent"] {
print("General Vendor Consent \(vendorConsent)")
}
IAB Vendor
if let vendorConsent = OTPublishersHeadlessSDK.shared.getVendorDetails(vendorID: "vendorID", for: VendorListMode.iab)?["consent"] {
print("IAB Vendor Consent \(vendorConsent)")
}
Google Vendor
if let vendorConsent = OTPublishersHeadlessSDK.shared.getVendorDetails(vendorID: "vendorID", for: VendorListMode.google)?["consent"] {
print("Google ATP Vendor Consent \(vendorConsent)")
}
Recommended Approaches
- Set an observer to listen for the
OTConsentUpdated
broadcast. In the callback, query for general vendor consent - Use one of the UI Interaction Listener events (such as
allSDKViewsDismissed
) and query for general vendor consent when it is triggered
Query Consent Status for Universal Consent Purposes
If your app is utilizing Universal Consent, you can query the consent status for Universal Consent Purposes, Custom Preferences, and Topics.
Get Purpose Consent
OTPublishersHeadlessSDK.shared.getUCPurposeConsent(purposeID: "Purpose ID")
Get Topic Consent
OTPublishersHeadlessSDK.shared.getUCPurposeConsent(topicID: "Topic ID", purposeID: "Purpose ID")
Get Custom Preferences Consent
OTPublishersHeadlessSDK.shared.getUCPurposeConsent(customPreferenceOptionID: "custPrefOptionID", customPreferenceID: "custPrefID", purposeID: "purposeID")
Returns
- 1 = Consent is given
- 0 = Consent is not given
- -1 = Consent has not been collected (The SDK is not initialized or purpose does not exist)
Listening for UI Interaction Events
Note: UI Interaction Events are only relevant if the app is using the out of the box OneTrust UI. If you have built your own UI, disregard this section.
When a User interacts with the OT SDK UI, the SDK sends an interaction event that the application can listen for and action on.
Use Case: The app needs to trigger certain actions based on interaction with the UI.
Use Case 2: In the event that broadcasts cannot be used to action on consent, the app can rely solely on interaction events and querying for consent to fire/suppress SDKs.
Example 1: User selects the "Confirm My Choices" button on the OT Preference Center UI, which saves their consent choices. An app might want to listen for the onPreferenceCenterConfirmChoices()
to show a success toaster to the user and navigate them to the App's home page.
Example 2: In lieu of broadcast events, the app can listen for allSDKViewsDismissed
to know when the OneTrust UI has been dismissed and query for user consent. It can then use this consent to fire/suppress SDKs.
Types of Events
Listed below are the supported OTEventListener
events:
Event | Description |
---|---|
onShowBanner() | Triggered when banner is shown |
onHideBanner() | Triggered when banner is closed |
onBannerClickedAcceptAll() | Triggered when user allows all consent from banner |
onBannerClickedRejectAll() | Triggered when user rejects all consent from banner |
onShowPreferenceCenter() | Triggered when Preference Center is displayed |
onHidePreferenceCenter() | Triggered when Preference Center is closed |
onPreferenceCenterAcceptAll() | Triggered when user allows all consent from Preference Center |
onPreferenceCenterRejectAll() | Triggered when user rejects all consent from Preference Center |
onPreferenceCenterConfirmChoices() | Triggered when user clicked on save choices after updating consent values from Preference Center |
onShowVendorList() | Triggered when vendor list UI is displayed from an IAB banner/ IAB Preference center |
onHideVendorList() | Triggered when vendor list UI is closed or when back button is clicked |
onVendorConfirmChoices() | Triggered when user updates vendor consent / legitimate interests purpose values and save the choices from vendor list |
onVendorListVendorConsentChanged() | Triggered when user updates consent values for a particular vendor id on vendor list UI |
onVendorListVendorLegitimateInterestChanged() | Triggered when user updates Legitimate interests values for a particular vendor id on vendor list UI |
onPreferenceCenterPurposeConsentChanged() | Triggered when user updates consent values for a particular category on Preference Center UI |
onPreferenceCenterPurposeLegitimateInterestChanged() | Triggered when user updates Legitimate interest values for a particular category on Preference Center UI |
onShowSDKList() | Triggered when the SDK List UI is displayed. |
onHideSDKList() | Triggered when the SDK List UI is closed or when back button is tapped. |
onSDKListSDKConsentChanged(sdkId: string, consentStatus: Int8) | Triggered when user opts in / out of an SDK on the SDK List view. |
allSDKViewsDismissed(interactionType: ConsentInteractionType) | Triggered when all the OT SDK Views are dismissed from the view hierarchy. |
The allSDKViewsDismissed(interactionType: ConsentInteractionType)
event is often used because:
- It is the last event to fire
- It only fires once all SDK UIs are dismissed from the view heirarchy
- It passes a
ConsentInteractionType
to provide context to application on the user's action.
ConsentInteractionType | Description |
---|---|
bannerAllowAll | The user has consented by clicking accept all button in Banner view. |
bannerRejectAll | The user has consented by clicking reject all button in Banner view. |
bannerClose | The user has clicked on close button in Banner view. |
preferenceCenterAllowAll | The user has consented by clicking allow all button from Preference Center. |
preferenceCenterRejectAll | The user has consented by clicking reject all button from Preference Center. |
preferenceCenterConfirm | The user has consented by clicking confirm button from Preference Center. |
preferenceCenterClose | The user has clicked on cancel button in Preference Center. |
vendorListConfirm | The user has consented by clicking confirm button from Vender List View. |
Setting it up
First, register the class that will be extended to handle the OTEventListener events.
//Swift
OTPublishersHeadlessSDK.shared.addEventListener(self)
//Objective-C
[[OTPublishersHeadlessSDK shared] addEventListener:self];
Then, extend the class to include the protocol OTEventListener methods.
// Swift
class YourCustomClass: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
OTPublishersHeadlessSDK.shared.addEventListener(self)
}
}
extension YourCustomClass: OTEventListener {
func onHideBanner() {}
func onShowBanner() {}
func onBannerClickedRejectAll() {}
func onBannerClickedAcceptAll() {}
func onShowPreferenceCenter() {}
func onHidePreferenceCenter() {}
func onPreferenceCenterRejectAll() {}
func onPreferenceCenterAcceptAll() {}
func onPreferenceCenterConfirmChoices() {}
func onPreferenceCenterPurposeLegitimateInterestChanged(purposeId: String, legitInterest: Int8) {}
func onPreferenceCenterPurposeConsentChanged(purposeId: String, consentStatus: Int8) {}
func onShowVendorList() {}
func onHideVendorList() {}
func onVendorListVendorConsentChanged(vendorId: String, consentStatus: Int8) {}
func onVendorListVendorLegitimateInterestChanged(vendorId: String, legitInterest: Int8) {}
func onVendorConfirmChoices() {}
func allSDKViewsDismissed(interactionType: ConsentInteractionType) {}
}
// ObjC
@interface YourCustomClass : UIViewController <OTEventListener>
@end
@implementation YourCustomClass
- (void)viewDidLoad {
[super viewDidLoad];
[[OTPublishersHeadlessSDK shared] addEventListener:self];
}
@end
@interface SceneDelegate : UIResponder <UIWindowSceneDelegate, OTEventListener> {
- (void)onHideBanner {}
- (void)onShowBanner {}
- (void)onBannerClickedAcceptAll {}
- (void)onBannerClickedRejectAll {}
- (void)onShowPreferenceCenter {}
- (void)onHidePreferenceCenter{}
- (void)onPreferenceCenterPurposeConsentChangedWithPurposeId:(NSString *)purposeId consentStatus:(int8_t)consentStatus {}
- (void)onPreferenceCenterAcceptAll {}
- (void)onPreferenceCenterRejectAll {}
- (void)onPreferenceCenterConfirmChoices {}
- (void)onPreferenceCenterPurposeLegitimateInterestChangedWithPurposeId:(NSString *)purposeId legitInterest:(int8_t)legitInterest {}
- (void)onShowVendorList {}
- (void)onHideVendorList {}
- (void)onVendorConfirmChoices {}
- (void)onVendorListVendorConsentChangedWithVendorId:(NSString *)vendorId consentStatus:(int8_t)consentStatus {}
- (void)onVendorListVendorLegitimateInterestChangedWithVendorId:(NSString *)vendorId legitInterest:(int8_t)legitInterest {}
- (void)allSDKViewsDismissed:(ConsentInteractionType)interactionType {}
}
// Swift
class YourCustomClass: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
OTPublishersHeadlessSDK.shared.addEventListener(self)
}
}
extension YourCustomClass: OTEventListener {
func onHideBanner() {}
func onShowBanner() {}
func onBannerClickedRejectAll() {}
func onBannerClickedAcceptAll() {}
func onShowPreferenceCenter() {}
func onHidePreferenceCenter() {}
func onPreferenceCenterRejectAll() {}
func onPreferenceCenterAcceptAll() {}
func onPreferenceCenterConfirmChoices() {}
func onPreferenceCenterPurposeLegitimateInterestChanged(purposeId: String, legitInterest: Int8) {}
func onPreferenceCenterPurposeConsentChanged(purposeId: String, consentStatus: Int8) {}
func onShowVendorList() {}
func onHideVendorList() {}
func onVendorListVendorConsentChanged(vendorId: String, consentStatus: Int8) {}
func onVendorListVendorLegitimateInterestChanged(vendorId: String, legitInterest: Int8) {}
func onVendorConfirmChoices() {}
func allSDKViewsDismissed(interactionType: ConsentInteractionType) {}
}
// ObjC
@interface YourCustomClass : UIViewController <OTEventListener>
@end
@implementation YourCustomClass
- (void)viewDidLoad {
[super viewDidLoad];
[[OTPublishersHeadlessSDK shared] addEventListener:self];
}
@end
@interface SceneDelegate : UIResponder <UIWindowSceneDelegate, OTEventListener> {
- (void)onHideBanner {}
- (void)onShowBanner {}
- (void)onBannerClickedAcceptAll {}
- (void)onBannerClickedRejectAll {}
- (void)onShowPreferenceCenter {}
- (void)onHidePreferenceCenter{}
- (void)onPreferenceCenterPurposeConsentChangedWithPurposeId:(NSString *)purposeId consentStatus:(int8_t)consentStatus {}
- (void)onPreferenceCenterAcceptAll {}
- (void)onPreferenceCenterRejectAll {}
- (void)onPreferenceCenterConfirmChoices {}
- (void)onPreferenceCenterPurposeLegitimateInterestChangedWithPurposeId:(NSString *)purposeId legitInterest:(int8_t)legitInterest {}
- (void)onShowVendorList {}
- (void)onHideVendorList {}
- (void)onVendorConfirmChoices {}
- (void)onVendorListVendorConsentChangedWithVendorId:(NSString *)vendorId consentStatus:(int8_t)consentStatus {}
- (void)onVendorListVendorLegitimateInterestChangedWithVendorId:(NSString *)vendorId legitInterest:(int8_t)legitInterest {}
- (void)allSDKViewsDismissed:(ConsentInteractionType)interactionType {}
}
Updated 9 months ago