- Requirements
- Installation
- Quick Start
- Setup and Usage
- ExportData
- Integration with Third-Party Libraries for Google Consent Mode
- Integration with Third-Party Libraries when Google Consent Mode is disabled
- Delaying Google Mobile Ads display until ATT and User Consent
Before integrating ClickioConsentSDKManager
(hereinafter reffered to as the Clickio SDK
), ensure that your application meets the following requirements:
- Minimum iOS Version: 15.0+
- Swift: 5.0+
Swift Package Manager
- File > Swift Packages > Add Package Dependency
- Add
https://github.com/ClickioTech/ClickioConsentSDK-IOS.git
- Select "Up to Next Major" with "1.0.7"
CocoaPods
- You can install ClickioConsentSDKManager pod from CocoaPods library:
platform :ios, '15.0'
use_frameworks!
target 'YourApp' do
pod 'ClickioConsentSDKManager', '~> 1.0.7'
end
- Or you can install ClickioConsentSDKManager pod directly from our open Github repository:
platform :ios, '15.0'
use_frameworks!
target 'YourApp' do
pod 'ClickioConsentSDKManager', :git => 'https://github.com/ClickioTech/ClickioConsentSDK-IOS.git', :tag => '1.0.7'
end
Pre-built Framework
- Open the release page, download the latest version of
ClickioConsentSDKManager
from the assets section. - Drag the
ClickioConsentSDKManager.xcframework
into your project and add it to the target (usually the app target). - Select your target, in the "General" Tab, find the "Frameworks, Libraries, and Embedded Content" section, set the
Embed Without Signing
toClickioConsentSDKManager
.
Here's the minimal implementation to get started: Import ClickioConsentSDKManager into your project file.
import ClickioConsentSDKManager
Make sure to replace string "Your Clickio Site ID" with yours Site id.
let clickioSdk = ClickioConsentSDK.shared
let config = ClickioConsentSDK.Config(siteId: "Your Clickio Site ID")
Task {
await clickioSdk.initialize(configuration: config)
clickioSdk.onReady {
clickioSdk.openDialog()
}
}
In this code after successful initialization, the SDK will open the Consent Window (a transparent UIViewController
with a WebView
).
Clickio SDK
supports two distinct scenarios for handling ATT permissions
. If your application collects user data and shares it with third parties for tracking purposes across apps and websites, you must:
-
Include the
NSUserTrackingUsageDescription
key in your app'sInfo.plist
file. -
Select an appropriate ATT permission display scenario provided by the SDK through
openDialog
method.
If your application already manages ATT permissions independently and includes the NSUserTrackingUsageDescription
key, you can skip this configuration step and proceed with the integration.
- make sure that user has given permission in the ATT dialog and only then perfrom
openDialog
method call! Showing CMP regardles given ATT Permission is not recommended by Apple. Moreover,openDialog
API call can be blocked by Apple until user makes their choice.
For more information about app tracking and privacy, see User Privacy and Data Use and App Privacy Details.
All interactions with the Clickio SDK should be done using the ClickioConsentSDK.shared
property to obtain the singleton instance of the SDK.
To initialize the SDK, use the initialize
method:
ClickioConsentSDK.shared.initialize(config: Config)
The SDK requires a configuration object with the following parameters:
class Config(
var siteId: String, // Your Clickio Site ID
var appLanguage: String? // Optional, two-letter language code in ISO 639-1
)
- Use the
setLogsMode
method to set-up desired logging mode: it can be.disabled
or.verbose
:
ClickioConsentSDK.shared.setLogsMode(.verbose)
Note: this method is optional. If you won't use it, by default you will receive logs of all levels in your console.
Use the onReady
callback to execute actions once the SDK is fully loaded:
ClickioConsentSDK.shared.onReady {
ClickioConsentSDK.shared.openDialog()
}
The SDK should not be used before onReady
is triggered, as it may lead to outdated data or errors.
Clickio SDK provides the openDialog
method to display the consent screen both in UIKit
and SwiftUI
projects.
ClickioConsentSDK.shared.openDialog(
mode: ClickioConsentSDK.DialogMode,
language: String? = nil,
in parentViewController: UIViewController? = nil,
attNeeded: Bool
) {
// This completion block will be called post-dismissal. Handle consent results,
// refresh UI, or execute post-CMP logic here.
print("Dialog closed")
}
-
mode
– Defines when the dialog should be shown. Possible values:DialogMode.default
– Opens the dialog if GDPR applies and user hasn't given consent.DialogMode.resurface
– Always forces dialog to open, regardless of the user’s jurisdiction, allowing users to modify settings for GDPR compliance or to opt out under US regulations.
-
language
– Allows you to explicitly specify language of consent dialog. This parameter is optional, and if not provided, the SDK will automatically use english language for presentation. -
in
– Allows you to explicitly specify on whichUIViewController
the dialog will be presented. This parameter is optional, and if not provided, the SDK will automatically use the root controller for presentation. -
attNeeded
– Allows you to specify whether an ATT permission is necessary.- If your app has it's own ATT Permission manager you just pass
false
inattNeeded
parameter and call your own ATT method.
- If your app has it's own ATT Permission manager you just pass
- Show ATT Permission first, then show Consent Dialog only if user has granted ATT Permission. This approach is recommended by Apple:
ClickioConsentSDK.shared.openDialog(
mode: ClickioConsentSDK.DialogMode,
attNeeded: true
) {
print("First scenario")
}
- Show only Consent Dialog bypassing ATT Permission demonstration:
ClickioConsentSDK.shared.openDialog(
mode: ClickioConsentSDK.DialogMode,
attNeeded: false
) {
print("Second scenario")
}
- we suggest you to use this approach only if you handle ATT Permission on your own.
- make sure that user has given permission in the ATT dialog and only then perfrom
openDialog
method call! Otherwise it will lead to incorrect work of the SDK: showing CMP regardles given ATT Permission is not recommended by Apple. Moreover,openDialog
API calls to SDK's domains will be blocked by Apple until user provides their permission in ATT dialog.
The SDK provides an onConsentUpdated
callback that is triggered whenever consent is updated:
ClickioConsentSDK.shared.onConsentUpdated {
// Handle consent update logic
}
To enable logging, use the following method:
ClickioConsentSDK.shared.setLogsMode(_ mode: EventLogger.Mode)
- `mode` parameter defines whether logging is enabled or not:
- `EventLogger.Mode.disabled` – Disables logging, default value
- `EventLogger.Mode.verbose` – Enables logging
ClickioConsentSDK.shared.checkConsentScope() -> String?
Returns the applicable consent scope as String.
- "gdpr" – The user is subject to GDPR requirements.
- "us" – The user is subject to US requirements.
- "out of scope" – The user is not subject to GDPR/US, other cases.
ClickioConsentSDK.shared.checkConsentState() -> ConsentState?
Determines the consent state based on the scope and force flag and returns ConsentState.
ConsentState.notApplicable
– The user is not subject to GDPR/US.ConsentState.gdprNoDecision
– The user is subject to GDPR but has not made a decision.ConsentState.gdprDecisionObtained
– The user is subject to GDPR and has made a decision.ConsentState.us
– The user is subject to US regulations.
ClickioConsentSDK.shared.checkConsentForPurpose(purposeId: Int) -> Bool?
Verifies whether consent for a specific TCF purpose has been granted by using IABTCF_PurposeConsents
string.
ClickioConsentSDK.shared.checkConsentForVendor(vendorId: Int) -> Bool?
Verifies whether consent for a specific TCF vendor has been granted by using IABTCF_VendorConsents
string.
ExportData
is a class designed to retrieve consent values from UserDefaults
. It provides methods to obtain various types of consent, including TCF, Google Consent Mode, and others.
Example of use
let exportData = ExportData()
var valueOfTCString = exportData.getTCString()
var listOfconsentedTCFPurposes = exportData.getConsentedTCFPurposes()
func getTCString() -> String?
Returns the IAB TCF v2.2 string if it exists.
func getACString() -> String?
Returns the Google additional consent string if it exists.
func getGPPString() -> String?
Returns the Global Privacy Platform (GPP) string if it exists.
func getConsentedTCFVendors() -> [Int]?
Returns the IDs of TCF vendors that have given consent.
func getConsentedTCFLiVendors() -> [Int]?
Returns the IDs of TCF vendors that have given consent for legitimate interests.
func getConsentedTCFPurposes() -> [Int]?
Returns the IDs of TCF purposes that have given consent.
func getConsentedTCFLiPurposes() -> [Int]?
Returns the IDs of TCF purposes that have given consent as Legitimate Interest.
func getConsentedGoogleVendors() -> [Int]?
Returns the IDs of Google vendors that have given consent.
func getConsentedOtherVendors() -> [Int]?
Returns the IDs of non-TCF vendors that have given consent.
func getConsentedOtherLiVendors() -> [Int]?
Returns the IDs of non-TCF vendors that have given consent for legitimate interests.
func getConsentedNonTcfPurposes() -> [Int]?
Returns the IDs of non-TCF purposes (simplified purposes) that have given consent.
func getGoogleConsentMode() -> GoogleConsentStatus?
Returns Google Consent Mode v2 flags wrapped into GoogleConsentStatus
struct if Google Consent Mode enabled, otherwise will return false
.
struct GoogleConsentStatus (
var analyticsStorageGranted = false
var adStorageGranted = false
var adUserDataGranted = false
var adPersonalizationGranted = false
var functionalityStorageGranted = false
var personalizationStorageGranted = false
var securityStorageGranted = false
)
Represents the status of Google Consent Mode.
analyticsStorageGranted
— Consent for analytics storage.adStorageGranted
— Consent for ad storage.adUserDataGranted
— Consent for processing user data for ads.adPersonalizationGranted
— Consent for ad personalization.functionalityStorageGranted
— Consent for functionality storage.personalizationStorageGranted
— Consent for personalization storage.securityStorageGranted
— Consent for security storage.
ClickioConsentSDK
supports automatic integration with external analytics and advertising platforms for Google Consent Mode V2 if enabled:
- Interactions with
ClickioConsentSDK
should be performed after initializing the third-party SDKs sinceClickioConsentSDK
only transmits consent flags. - Ensure that you have completed the required tracking setup for Adjust, Airbridge, or AppsFlyer before integrating
ClickioConsentSDK
. This includes proper initialization and configuration of the SDK according to the vendor’s documentation.
If the Firebase Analytics SDK is present in the project, the Clickio SDK will automatically send Google Consent flags to Firebase if Clickio Google Consent Mode integration enabled.
ClickioConsentSDK transmits consent flags immediately if they were updated after showing the consent dialog (when onConsentUpdated
is called) or during initialization if the consent has been accepted.
After successfully transmitting the flags, a log message will be displayed (if logging is enabled) confirming the successful transmission. In case of an error, an error message will appear in the logs. You may need to update Firebase Analytics to a newer version in your project.
If any of these SDKs (Adjust, Airbridge, AppsFlyer) are present in the project, ClickioConsentSDK
will automatically send Google Consent flags to them if Clickio Google Consent Mode integration enabled.
However, interactions with ClickioConsentSDK
should be performed after initializing the SDK since ClickioConsentSDK
only transmits consent flags, while the initialization and configuration of the libraries are the responsibility of the app developer.
After successfully transmitting the flags, a log message will be displayed (if logging is enabled) to confirm the successful transmission. In case of an error, an error message will appear in the logs. You may need to update the SDK you are using (Adjust, Airbridge, or AppsFlyer) to a newer version in your project.
For other libraries, you can use the getGoogleConsentMode
method from the ExportData
class to retrieve the GoogleConsentStatus
.
For example, you can subscribe to the onConsentUpdated
callback and call getGoogleConsentMode
within it.
let exportData = ExportData()
ClickioConsentSDK.shared.onConsentUpdated {
var googleConsentFlags = exportData.getGoogleConsentMode()
if googleConsentFlags != nil {
// Send values to other SDK
}
}
If you need to send consent data on each subsequent app launch, it is recommended to wait for the onReady
callback and then call getGoogleConsentMode
.
Keep in mind: getGoogleConsentMode
can return nil
if Google Consent Mode is disabled or unavailable.
If Clickio Google Consent Mode integration is disabled you can set consent flags manually.
Firebase Analytics example:
ClickioConsentSDK.shared.onConsentUpdated {
let purpose1 = ClickioConsentSDK.shared.checkConsentForPurpose(purposeId:1)
let purpose3 = ClickioConsentSDK.shared.checkConsentForPurpose(purposeId:3)
let purpose4 = ClickioConsentSDK.shared.checkConsentForPurpose(purposeId:4)
let purpose7 = ClickioConsentSDK.shared.checkConsentForPurpose(purposeId:7)
let purpose8 = ClickioConsentSDK.shared.checkConsentForPurpose(purposeId:8)
let purpose9 = ClickioConsentSDK.shared.checkConsentForPurpose(purposeId:9)
let adStorage: ConsentStatus = purpose1! ? .granted : .denied
let adUserData: ConsentStatus = (purpose1! && (purpose7 != nil)) ? .granted : .denied
let adPersonalization: ConsentStatus = (purpose3! && (purpose4 != nil)) ? .granted : .denied
let analyticsStorage: ConsentStatus = (purpose8! && (purpose9 != nil)) ? .granted : .denied
let consentSettings: [ConsentType: ConsentStatus] = [
.adStorage: adStorage,
.adUserData: adUserData,
.adPersonalization: adPersonalization,
.analyticsStorage: analyticsStorage
]
Analytics.setConsent(consentSettings)
}
More about Consent Mode flags mapping with TCF and non-TCF purposes
Sometimes you need to ensure that both Apple's App Tracking Transparency prompt and user consent decision have been recorded before initializing and loading Google Mobile Ads. To implement this flow:
- Wait for ATT authorization and CMP readiness
- First present the ATT prompt.
- Then open Clickio SDK's consent dialog via
ClickioConsentSDK.shared.openDialog(...)
.
- Use Clickio SDK's callbacks
- In the
onReady
callback, you know that SDK is ready & the CMP dialog can be shown. - In the
onConsentUpdated
callback, you know the user's consent decision has been recorded.
- Initialize and load ads only after consent
- Inside
onConsentUpdated
&onReady
callbacks, ensure thatcheckConsentState() != gdprNoDecision
has been confirmed. - Then call
MobileAds.shared.start(...)
and load your banner.
This ensures that Google Mobile Ads is only started — and the banner only fetched — once you've obtained both ATT permission and explicit user decision from the CMP.
Note: Avoid double-starting
– E.g. if ads already started on initial accept, don’t restart after a later “resurface” consent change.
Code example:
// Keep track of whether Google Mobile Ads has already been started
private var adsStarted = false
func setupConsentAndAds() {
// 1) Listen for SDK ready (CMP can show)
ClickioConsentSDK.shared.onReady {
// 2) Show CMP
ClickioConsentSDK.shared.openDialog(mode: .default, attNeeded: true)
// 3) Immediately check prior consent
self.tryStartAdsIfAllowed()
}
// 4) When consent changes, check again
ClickioConsentSDK.shared.onConsentUpdated {
self.tryStartAdsIfAllowed()
}
}
private func tryStartAdsIfAllowed() {
guard let state = ClickioConsentSDK.shared.checkConsentState(),
state != .gdprNoDecision else { return }
// 5) Only start once
guard !adsStarted else {
print("Ads already started")
return
}
print("Consent allows ads – starting Google Mobile Ads")
GADMobileAds.sharedInstance().start(completionHandler: nil)
adsStarted = true
}