Introduction
The Osano ConsentSDK for iOS is a native framework that integrates with the Consent Management Platform on the Osano Website. It is necessary to have an account, and a Cookie Consent configuration created and published in order for this SDK to be able to record end-user consents.
How do I use it?
ConsentManager
First, you must create an instance of the ConsentManager
object. This object contains the general
configuration parameters that will be used throughout the life of the
application.
- Swift
- Objective-C
import ConsentSDK
// ...
let consentManager = ConsentManager(
customerId: "my_customer_id",
configId: "my_config_id",
consentingDomain: "my.consenting.domain",
extUsrData: "my_user_data"){ error in
if let error = error {
print("Initialization failed with error: (error)")
} else {
print("ConsentManager initialized successfully")
}
}
@import ConsentSDK;
// ...
self.consentManager = [[ConsentManager alloc]
initWithCustomerId: @"my_customer_id"
configId: @"my_config_id"
consentingDomain: @"my.consenting.domain"
extUsrData: @"my_user_data"
completion: { (error) in
if let error = error {
println("Initialization failed with error: (error)")
} else {
println("ConsentManager initialized")
}
];
Note that the configId
and customerId
parameters are not optional, and must match the values of your configuration on the Osano website.
The completion handler lets you to know when initialization is completed successfully, allowing you load the UI with the correct locale and UI configurations.
UI Builder
Now that you have created an instance of the ConsentManager
, you can
use it to create and show consent messages in your application. There
are two types of dialogues available to show in the SDK, and (depending on the geo-location of your end-user) the UI for each will look different. This is due to legal requirements that are in place for the end-user's geo-location. Rest assured, these UI differences are intentional and necessary to maintain legal compliance for the location of your users.
The dialogue UI can be personalized via the following builder parameters:
- Swift
- Objective-C
let consentUiBuilder = ConsentUiBuilder(
storagePolicyHref: nil,
additionalLinkHref: nil,
languageCode: nil,
consentManager: consentManager,
hideDisclosures: true
)
// You can also provide custom color overrides for the UI
let consentUiBuilder = ConsentUiBuilder(
linkColor: nil,
toggleButtonOnColor: nil,
toggleOnBackgroundColor: nil,
toggleButtonOffColor: nil,
toggleOffBackgroundColor: nil,
buttonBackgroundColor: nil,
buttonForegroundColor: nil,
dialogBackgroundColor: nil,
dialogForegroundColor: nil,
buttonDenyBackgroundColor: nil,
buttonDenyForegroundColor: nil,
infoDialogBackgroundColor: nil,
infoDialogForegroundColor: nil,
infoDialogOverlayColor: nil,
storagePolicyHref: nil,
languageCode: nil,
consentManager: consentManager,
hideDisclosures: true
)
self.consentUiBuilder = [[ConsentUiBuilder alloc]
initWithLinkColor: nil
toggleButtonOnColor: nil
toggleOnBackgroundColor: nil
toggleButtonOffColor: nil
toggleOffBackgroundColor: nil
buttonBackgroundColor: nil
buttonForegroundColor: nil
dialogBackgroundColor: nil
dialogForegroundColor: nil
buttonDenyBackgroundColor: nil
buttonDenyForegroundColor: nil
infoDialogBackgroundColor: nil
infoDialogForegroundColor: nil
infoDialogOverlayColor: nil
storagePolicyHref: nil
additionalLinkHref: nil
languageCode: nil
consentManager: consentManager
hideDisclosures: true
];
If you do not provide values for the color overrides, or other optional parameters, the SDK will use the values that are set in your configuration on the Osano website.
Display Modes
The UI may de shown in 2 different ways:
Dialog
The Dialog View Controller allows you to show a consent message and the required data storage preferences based on the country the device is in. The SDK takes care of figuring out which consent variant must be shown based on the device's locale. You can choose the presentation type with the PresentationType enum
- Swift
- Objective-C
public enum PresentationType: Int {
case modal
case fullScreen
case bottomSheet
}
typedef SWIFT_ENUM(NSInteger, PresentationType, open) {
PresentationTypeModal = 0,
PresentationTypeFullScreen = 1,
PresentationTypeBottomSheet = 2,
};
To create the dialogue and show it, use the showDialogViewController
method:
- Swift
- Objective-C
let type = ConsentUiBuilder.PresentationType.fullScreen
consentUiBuilder.showDialogViewController(presenterViewController: self, type: type) { (categories) in
print(categories)
} deny: {
print("User denied")
}
[self.consentUiBuilder
showDialogViewControllerWithPresenterViewController: self
type: type
success: ^(NSArray * categories) {
for (NSString *category in categories) {
NSLog(@"%@", category);
}
} deny: ^{
NSLog(@"User denied");
}];
The dialog (depending on the end-user's geo-location) may have an automatic timeout, which will grant consent upon closure. This is normal functionality for specific global regions.
If a the completion callback notifies you that the end-user declined to consent, this does not mean they denied consent. It simply means that they did not make a selection.
The Drawer UI will not allow the user to dismiss the modal without making a selection, but the Dialog UI (in some geo-locations) will allow the user to dismiss the modal without making a selection. This is why it is important to check the categories
array in the completion callback to determine if the user has actually declined to consent.
Drawer
The Drawer View Controller allows you to display all consent
categories using a built-in UI. In this dialogue, the user can choose to
enable or disable any of the consent categories.
To user the view controller and show it, use the method showDrawerViewController
- Swift
- Objective-C
guard let viewController = consentUiBuilder.categoriesViewController else { return }
consentUiBuilder.showDrawerViewController { (categories) in
// Do something with the categories
}
let drawerNavigationController = UINavigationController(rootViewController: viewController)
drawerNavigationController.modalPresentationStyle = .formSheet
present(drawerNavigationController, animated: true, completion: nil)
OsanoCategoriesViewController *viewController = self.consentUiBuilder.categoriesViewController;
[self.consentUiBuilder showDrawerViewControllerWithSuccess:
^(NSArray *categories) {
// Do something with the categories
}];
UIViewController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:navigationController animated:true completion:nil];
Locale
By default the SDK will use the device's preferred language when showing the dialog or drawer. If you want to force a specific language, you can provide a languageCode
parameter to the ConsentUiBuilder
initializer. The languageCode
parameter should be a valid ISO 639-1 language code.
The following methods are available to assist you in using the right language based on your app's needs:
getSupportedLanguages
ConsentUiBuilder.getSupportedLanguages() -> [String]
Returns the languages supported by the SDK.
isLanguageSupported
ConsentUiBuilder.isLanguageSupported(language: String) -> Bool
Returns whether the language is supported by the SDK.
Using Custom UI
If the SDK's built-in UI does not fit your requirements, you can use the
ConsentManager
's APIs and integrate them to your own app's UI:
To save (locally and remotely) new consent categories use:
- Swift
- Objective-C
let analytics = OsanoCategoryObject.factory(category: .essential) // .analytics, .essential, .marketing, .personalization, .opt_out
consentManager.consent(objectCategories: [analytics])
OsanoCategoryObject *categoryEssential = [OsanoCategoryObject factoryWithCategory: OsanoCategoryEssential];
OsanoCategoryObject *categoryMarketing = [OsanoCategoryObject factoryWithCategory: OsanoCategoryMarketing];
OsanoCategoryObject *categoryAnalytics = [OsanoCategoryObject factoryWithCategory: OsanoCategoryAnalytics];
OsanoCategoryObject *categoryPersonalization = [OsanoCategoryObject factoryWithCategory: OsanoCategoryPersonalization];
OsanoCategoryObject *categoryOpt = [OsanoCategoryObject factoryWithCategory: OsanoCategoryOpt_out];
NSArray *consentArray = [NSArray arrayWithObjects: categoryEssential, categoryMarketing, categoryAnalytics, categoryPersonalization, categoryOpt, nil];
[self.consentManager consentWithObjectCategories: consentArray];
To get the list of consented categories (local storage):
- Swift
- Objective-C
guard let consentedArray = consentManager.userConsentedCategories() as? [String] else { return }
let consentedString = consentedArray.joined(separator: ", ")
print(consentedString)
NSArray *consentedArray = [self.consentManager userConsentedCategories];
NSString *consentedString = [consentedArray componentsJoinedByString:@", "];
NSLog(@"%@", consentedString);
To get whether the user has already gone through the consent process:
- Swift
- Objective-C
let userConsented = consentManager.userConsent()
BOOL userConsented = [self.consentManager userConsent];
Google Consent Mode
The SDK supports Google's Consent Mode. To enable, turn on Google Consent Mode in your configuration on the Osano website and follow instructions below:
- Add the following Analytics extension to your project
- Swift
import FirebaseAnalytics
import Foundation
extension Analytics {
static func convertToFirebaseConsentType(from category: String) -> ConsentType? {
switch category {
case "analytics_storage": return .analyticsStorage
case "ad_storage": return .adStorage
case "ad_user_data": return .adUserData
case "ad_personalization": return .adPersonalization
default:
return nil
}
}
static func convertToFirebaseConsentStatus(from status: String) -> ConsentStatus? {
switch status {
case "granted": return .granted
case "denied": return .denied
default:
return nil
}
}
static func setConsent(using osanoGoogleConsent: [String: String]) {
var firebaseConsentMap: [ConsentType: ConsentStatus] = [:]
osanoGoogleConsent.forEach { key, value in
let consentType = Analytics.convertToFirebaseConsentType(from: key)
let consentStatus = Analytics.convertToFirebaseConsentStatus(from: value)
guard let consentType = consentType, let consentStatus = consentStatus else {
return
}
firebaseConsentMap[consentType] = consentStatus
}
Analytics.setConsent(firebaseConsentMap)
}
}
- Use the
ConsentManager.withGoogleConsent
callback to trigger Firebase Analytics updates
- Swift
consentManager.withGoogleConsent { (googleConsent) in
Analytics.setConsent(using: googleConsent)
}