Wiki

Clone wiki

Consent Handling Sample / AATKit 3 migration

Consent handling

Index:

  1. Consent handling
  2. Reacting to changed consent
  3. Skip rules if no TCF2.0 consent
  4. SampleApp

Consent Handling

AATKit has 3 types of consent to choose from: AATManagedConsent, AATSimpleConsent or AATVendorConsent

Setup

if you want to use AATManagedConsent with AATCMPOgury, please add pod 'AATKit/OguryCMP' to your pod file and add this line import AATOguryCMPAdapter to your code,

With the introduction of IAB TCF2.0, AddApptr will no longer act as a CMP. Instead, we provide wrappers allowing for easily integrating third-party CMPs. The AATManagedConsent provides the following methods:

  • Init: init?(cmp: AATCMPProtocol?, delegate: AATManagedConsentDelegate), where:
    • cmp - The instance of CMP to be used, currently either AATCMPGoogle or AATCMPOgury.
    • delegate - The delegate that will be notified about CMP events. Must not be null.
  • func showIfNeeded(_ viewController: UIViewController) - Presents the consent screen ONLY if it is required by the used CMP (for example if no user consent has been set yet). It is advised to always call this method when the first app controller is presented.
  • func editConsent(_ viewController: UIViewController) - Presents the consent screen, allowing the user to change consent settings.
  • func reload(_ viewController: UIViewController) - Tells the CMP to reload. Does not need to be used unless some error occurs. You can call this method for example after receiving ManagedConsentDelegate.managedConsentCMPFailedToLoad(ManagedConsent, String) callback.

If you use AATManagedConsent, you should make your class conform to the AATManagedConsentDelegate. If there is no IAB consent string in the NSUserDefaults, -managedConsentNeedsUserInterface will be called, which will probably happen if the app launches for the first time.

Instead of:

Code example (Swift)

var consent: AATManagedConsent?
extension AppDelegate: AATManagedConsentDelegate {
    func cmpNeedsUI(_ managedConsent: AATManagedConsent) {
        // Get your rootViewController
        self.consent.showIfNeeded(vc)
    }

    func managedConsentCMPFinished(with state: AATManagedConsentState) {
      // The user finished his action with CMP with the state as the user chosen state
    }

    func managedConsentCMPFailed(toLoad managedConsent: AATManagedConsent, error string: String) {
        // CMP failed to loadwith the error message. You may want to to call managedConsent.reload()
    }

    func managedConsentCMPFailed(toShow managedConsent: AATManagedConsent, error string: String) {
        // CMP failed to show with the error message
    }
}

Use:

Code example (Swift)

var consent: AATManagedConsent?
extension AppDelegate: AATManagedConsentDelegate {
    func managedConsentNeedsUserInterface(_ managedConsent: AATManagedConsent) {
        // Get your rootViewController
        self.consent.showIfNeeded(vc)
    }

    func managedConsentCMPFinished(with state: NonIABConsent) {
      // The user finished his action with CMP with the state as the user chosen state
    }

    func managedConsentCMPFailedToLoad(_ managedConsent: AATManagedConsent, with error: String) {
        // CMP failed to loadwith the error message. You may want to to call managedConsent.reload()
    }

    func managedConsentCMPFailedToShow(_ managedConsent: AATManagedConsent, with error: String) {
        // CMP failed to show with the error message
    }
}

the NonIABConsent can be one of the following enum cases:

public enum NonIABConsent: Int {
    /**
    * Unknown - if the user has never set a consent state.
    */
    case unknown

    /**
    * Consent has been granted by the user.
    */
    case obtained

    /**
    * Consent has been partially granted by the user.
    */
    case custom
    /**
    * Consent has been declined by the user.
    */
    case withheld
}

CMP implementations

Google CMP

For now, we provide two CMP implementations: * Requires appId to be added to Info.plist file, like

<key>GADApplicationIdentifier</key>
<string>YOUR-APP-ID</string>
* Requires the GoogleCMP dependency to work by adding the following to your Podfile:
pod 'AATKit/GoogleCMP'
Code example (Swift)
import AATGoogleCMPAdapter

let cmp = AATCMPGoogle()
var consent: AATManagedConsent?
func configureAATKit() {
    let configuration = AATConfiguration()
    ...
    cmp = AATCMPGoogle()
    consent = AATManagedConsent(cmp: cmp, delegate: self)
    configuration.consent = consent

    AATSDK.initAATKit(with: configuration)
    ...
    self.consent?.showIfNeeded(<YourCurrentController>)
}
Code example (Objective-C)
- (void)configureAATKit {
    AATConfiguration* configuration = [[AATConfiguration alloc] init];
    ...
    self.cmp = [[AATCMPGoogle alloc] init];
    self.consent = [[AATManagedConsent alloc] initWithCMP:self.cmp delegate:self];
    configuration.consent = self.consent;
    ...
     [AATSDK initAATKitWith:configuration];
}

Ogury CMP

  • Requires the Ogury dependency to work by adding the following to your Podfile:

pod 'AATKit/OguryCMP'
* Requires Ogury Asset Key as an initializer parameter

Code example (Swift)

func configureAATKit() {
    let configuration = AATConfiguration()
    ...
    cmp = AATCMPOgury(with: "YourAssetKey")
    guard let cmp = cmp else {
        // Shouldn't be nil
    }
    consent = AATManagedConsent(cmp: cmp, delegate: self)
    configuration.consent = consent
    ...

    self.consent?.showIfNeeded(<YourCurrentController>)

}
Code example (Objective-C)
- (void)configureAATKit {
    AATConfiguration* configuration = [[AATConfiguration alloc] init];
    ...

    self.cmp = [[AATCMPOgury alloc] initWith:"YourAssetKey"];
    self.consent = [[AATManagedConsent alloc] initWithCMP:self.cmp delegate:self];
    configuration.consent = self.consent;
    ...
    [AATSDK initAATKitWith:configuration];
}

To set if the user has given or withheld consent for the collection and use of personal data (used for non-IAB partners), use AATSimpleConsent default initializer and pass any value of the NonIABConsent enum

  • .obtained if the user has given the consent
  • .withheld if the user has declined
  • .unknown if the user has not set a preference

If AATSimpleConsent is used, it will automatically read the IAB Consent String stored (by third-party CMP) in UserDefaults (if available).

Code example (Swift)

func configureAATKit() {
    let configuration = AATConfiguration()
    ...
    let consent = AATSimpleConsent(nonIABConsent: .obtained)
    configuration.consent = consent
    ...
    AATSDK.initAATKit(with: configuration)
}
Code example (Objective-C)

- (void)configureAATKit {
    AATConfiguration* configuration = [[AATConfiguration alloc] init];
    ...
    AATSimpleConsent *consent = [[AATSimpleConsent alloc] initWithNonIABConsent:NonIABConsentObtained];
    configuration.consent = consent;
    ...
    [AATSDK initAATKitWith:configuration];
}

For publishers not using the ManagedConsent, we have introduced another type of Consent for GDPR-compliance. It can be considered a more advanced version of SimpleConsent, allowing to pass network-specific consent status. To use it, you need to implement the AATVendorConsentDelegate and initialize AATKitConfiguration's consent with a AATVendorConsent instance. It will also automatically read the IAB TCF2.0 Consent String stored (by third-party CMP) in NSUserDefaults (if available). This means that the value returned by getConsentForAddApptr will only be checked if there is no IAB TCF2.0 consent stored.

Code example (Swift)

func configureAATKit() {
    let configuration = AATConfiguration()
    ...
    let consent = AATVendorConsent(delegate: self)
    configuration.consent = consent
    ...
    AATSDK.initAATKit(with: configuration)
}
// MARK: AATVendorConsentDelegate
func getConsentForNetwork(_ network: AATAdNetwork) -> NonIABConsent {
    //decide for each ad network
    return .obtained
}

func getConsentForAddapptr() -> NonIABConsent {
    return .obtained
}
Code example (Objective-C)

- (void)configureAATKit {
    AATConfiguration* configuration = [[AATConfiguration alloc] init];
    ...
    AATVendorConsent *consent = [[AATVendorConsent alloc] initWithDelegate:self];
    configuration.consent = consent;
    ...
    [AATSDK initAATKitWith:configuration];
}

#pragma mark - AATVendorConsentDelegate
-(enum NonIABConsent)getConsentForAddapptr {
    return NonIABConsentObtained;
}

- (enum NonIABConsent)getConsentForNetwork:(enum AATAdNetwork)network {
    return NonIABConsentObtained;
}

Reacting to changed consent

To make sure AATKit and all the networks use updated consent configuration,It is necessary to reconfigure AATKit every time consent is changed by the user (CMP is closed).

Code example (Objective-C)

AATRuntimeConfiguration* aatRuntimeConfiguration = [[AATRuntimeConfiguration alloc] init];
AATVendorConsent *consent = [[AATVendorConsent alloc] initWithDelegate:self];
aatRuntimeConfiguration.consent = consent;
[AATSDK reconfigureWithConfiguration: aatRuntimeConfiguration];
Code example (Swift)
let aatRuntimeConfiguration = AATRuntimeConfiguration()
let consent = AATVendorConsent(delegate: self)
aatRuntimeConfiguration.consent = consent
AATSDK.reconfigure(configuration: aatRuntimeConfiguration)

  • AATKit skips rules for AdNetworks in case that the user didn't give consent for that AdNetwork.
  • AATKit skips rules for AdNetworks if the user didn't allow the app for tracking
  • This feature is disabled by default and to enable it:

Code example (Swift)

func configureAATKit() {
    let configuration = AATConfiguration()
    ...
    configuration.shouldSkipRules = true
    ...
    AATKit.initialize(with: configuration)
}
Code example (Objective-C)

- (void)configureAATKit {
    AATConfiguration* configuration = [[AATConfiguration alloc] init];
    ...
    configuration.shouldSkipRules = YES;
    ...
    [AATKit initializeWithConfiguration:configuration];
}

SampleApp

Updated