Info
Content

[iOS] 1. consentmanager SDK Integration

The consentmanager SDK for iOS apps implements and provides functionality to inform the user about data protection and ask and collect consent from the user. It enables app-developers to easily integrate the consentmanager service into their app.

How it works

  1. Integrate the SDK into the app and configure the SDK settings
  2. Once the SDK is intergated into an app, the SDK will provide functions for the app developer in order to retrieve consent data
  3. As soon as the app starts, the SDK will automatically retrieve information from the consentmanager servers in order to prepare the SDK for its usage.
  4. It is recommended, that on startup of the app, the app creates an instance of class CMPConsentTool. Once the this is created, the SDK will automatically show the consent screen if necessary.
  5. When the app wants to process personal data, it should "ask" the SDK if consent was given for the specific purpose and vendor.

Installation via Cocoapod

Find the compatible native SDK Versions here.

Add Library with Cocoapod

You can install the consentmanager SDK by adding CmpSdk to your Podfile as explained in the example below:

target 'YourProject' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!
  pod 'CmpSdk'

  target 'YourProjectTests' do
    inherit! :search_paths
     # Pods for testing
  end
  
...
      
end

Once this is done, you need to run pod install in your project directory to install the consentmanager SDK. After this, please open the *.xcworkspace and build. 

After you have followed all the steps, your dependency should be installed, and you can proceed and use it in your project.

Installation via Swift Package Manager

  1. Open Swift Package Manager.
  2. Go to File > Swift Packages > Add Package Dependency.
  3. Add the SDK Repository URL
    You'll now see a new window where you can enter the URL of the SDK's repository.Most SDKs are hosted on GitHub, so the URL will often look like
    https://github.com/iubenda/cm-sdk-xcframework.git
    After entering the URL, click Next.
  4. Select the SDK Version
    SPM will now fetch the repository and ask you to select a version.
    You can choose to add the package by selecting a version rule:
    - Up to Next Major: This will update the package up to the next major version. It is the recommended option as it adds updates which do not have breaking changes.
    - Up to Next Minor: This will update the package up to the next minor version.
    - Exact: This will lock the package to a specific version. No updates will be installed.
    Select the version you wish to use and click Next.
  5. Add the SDK to your Target
    On the next screen, select the targets that you want to add the package dependency to. Targets are usually your app and any tests that you might have. Click Finish to complete the process.
  6. Import the SDK
    Now that the SDK has been added to your project, you need to import it to use it.Go to the file where you want to use the SDK and add the following import statement at the top:
import CmpSdk

Initiate the SDK

With the app-start (usually your viewDidLoad function) you must create an instance of class CMPConsentTool.  This will automatically fetch the necessary data from our server and determine if the consent screen needs to be shown or not. If so, the SDK will automatically show the consent screen at this point, collect the data and provide the data to the app. The instance can then be used in order to get consent details from the SDK in order to use it in the app.

let cmpConfig : CmpConfig = CmpConfig.shared.setup(withId: config.appId, domain: config.domain, appName: config.appName, language: config.language);
// optional configure additional parameter
cmpConfig.isAutomaticATTRequest = true;

// initialize the SDK
cmpConsentTool = CMPConsentTool(cmpConfig: cmpConfig)
        
/** Optionally chain callbacks */
cmpConsentTool = cmpConsentTool.withOpenListener(onOpen)
            				   .withOnCmpButtonClickedCallback(onButtonClickedEvent)
            				   .withCloseListener(onClose)
           					   .withErrorListener(onCmpError)

Please note that is is important to initialize the SDK in the viewDidLoad Method. Otherwise the view may not be ready to use and the SDK may fail.

Please ensure to use the correct configuration data. The configuration data can be found in your consentmanager account at Menu > CMPs > Get Code for Apps > Code-ID

SwiftUI

To integrate the SDK in a SwiftUI environment you must provide a UIViewController which is wrapped inside a UIViewControllerRepresentable. You can find more information about on the official apple documentation. Before integrating the SDK make sure you already integrated the Module in your project. 

1. We start with creating a usual UiViewController similar to the examples for Swift/Objective C

import UIKit
import consentmanager


class CmpViewController: UIViewController {
       struct config {
        static let domain = "Server-Domain from consentmanager, e.g. delivery.consentmanager.net"
        static let appId = "Code-ID from consentmanager, e.g. b238acdf1a..."
        static let appName = "testApp"
        static let language = "DE"
    }

    var cmpManager: CMPConsentTool? = nil
    
    private func setupCmpConfig() {
        // Do any additional setup after loading the view.
        let cmpConfig : CmpConfig = CmpConfig.shared.setup(withId: config.appId, domain: config.domain, appName: config.appName, language: config.language);
        cmpConfig.isAutomaticATTRequest = true;
        cmpManager = CMPConsentTool(cmpConfig: cmpConfig)
            .withErrorListener(onCMPError)
            .withCloseListener(onClose)
            .withOnCMPNotOpenedListener(onCMPNotOpened).initialize()
    }
    
    func onClose() -> Void {
        NSLog("closed event");
    }

    func onOpen() -> Void {
        NSLog("opened event");
    }

    func onCMPNotOpened() -> Void {
        NSLog("not opened event");
    }
    
    override func viewDidLoad() {
    	super.viewDidLoad()
    	setupCmpConfig();
       
        let button = UIButton.init(frame: CGRect.init(x: 10, y: 100, width: 100, height: 50))
        button.setTitle("Consent", for: .normal)
        button.backgroundColor = .red
        button.addTarget(self, action: #selector(onShowConsentClicked), for: .touchUpInside)
        self.view.addSubview(button)
    }
    
    /**
     * Show consent button was clicked
     */
    @objc func onShowConsentClicked(sender: UIButton!) {
        cmpManager!.openView()
    }
}

2. In order to use the controller in the swiftUI you have to create a UIViewControllerRepresentable which is instantiating the CmpViewController:

import SwiftUI

struct CmpViewControllerRepresentable: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> UIViewController {
        let cmpViewController = CmpViewController()
        
        return cmpViewController
    }
    
    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
    }
}

3. Now we can use the ControllerView inside the SwiftUI context :

import SwiftUI

@main
struct cmpApp: App {
    var body: some Scene {
        WindowGroup {
            CmpViewControllerRepresentable()
        }
        
        
    }
}

An example project is provided here

To implement the functionality where certain domains are whitelisted and, when accessed within the consent platform (CMP) WebView, are not opened in an external browser like Safari but within the WebView itself, you can implement a callback mechanism to perform custom actions based on the domain, such as opening another ViewController:

cmpConfig.domainWhitelist = ["add your domains to be whitelisted"]
        
cmpManager.withOnCmpLinkClickListener({ url, decisionHandler in
                //check URL and add the nav action
                decisionHandler!.pointee = WKNavigationActionPolicy.allow
                decisionHandler!.pointee = WKNavigationActionPolicy.cancel
                // return shouldCloseWebView (true) or stay open (false)
                return true
            })        

 

Using the SDK

In order to check whether a vendor or purpose have consent, you can use the two methods:

if(consentTool!.hasPurposeConsent("52"))
{
    if(consentTool!.hasVendorConsent("s26"))
    {
        //do something with data
    }
}

Both methods hasPurposeConsent and hasVendorConsent require two parameter:

  • id - String of the vendor or purpose ID. Please note that vendor IDs can have different formats ("123", "s123" and "c123"), please double-check with Menu > Vendors and Menu > Purposes in your consentmanager account.
  • isIABVendor / isIABPurpose - If the vendor or purpose is a vendor/purpose that follows the IAB TCF standard, you will need to set a true, otherwise a false.

Remember: All vendor that do not belong to the IAB have IDs starting with a "s" or "c" (e.g. "s123"); vendors that belong to the IAB have IDs not starting with a "s" or "c".

Re-Opening the Consent Screen

In order to allow the user to change the choices, you can simply call openView()

cmpConsentTool!.openView()

In some cases an native app might contain webviews in order to display certain things like advertising oder content. In order to transmit the consent information from the SDK to the webview, please use the function:

consentData = CmpConsentTool.exportCmpString();

This will export the consent information and all further data that is needed by the CMP. You can then pass this information to the CMP that is in your webview by adding it to the URL that is called in the webview:

myWebView.loadURL("https://mywebsite.com/....#cmpimport=" + consentData);

/** to pass the att status you can use the cmpatt parameter (1=accepted, 2=declined) */

myWebView.loadURL("https://mywebsite.com/....#cmpimport=" + consentData + "&cmpatt=1");

Integration with Apple Tracking Transparency (ATT)

In case you are using tracking or analytics in your app, we recommend to read the guid on ATT implementation here.

Creating a custom layout

For a custom layout there are 2 callback functions which provide the viewController and the uiView. In the example shown below you can see how to customise the layout

        let cmpLayout = CmpLayout.default()
        cmpLayout?.cornerRadius = 10.0
        cmpLayout?.customLayout = CGRect(x: 0, y: 0, width: 200, height: 300)
        cmpManager = CMPConsentTool(cmpConfig: cmpConfig)
            .withCmpViewControllerConfigurationBlock({ viewController in
                viewController?.modalPresentationStyle = .formSheet
                //example of customizing controller
            })
            .withCmpViewConfigurationBlock({ uiView in
                cmpLayout?.apply(to: uiView)
                // or use your own uiView logic 
            })

Custom Event Listeners

To add additional process logic you can make use of Event Listeners. Following Event Listeners are available:

Name

Occurrs

 

CmpOpenListener

Listener for Event when CMP opened

CmpCloseListener

Listener for Event when CMP is closed

CmpNotOpenedListener

Listener for Event when CMP doesn't need to be opened

CmpErrorListener

Listener will be called, if an error occurs while calling the Server or showing the view.

CmpButtonClickedListener

Listener for Event when Button is clicked and Consent layer is closing

CmpATTrackingStatusChangedListener

Listener for ATTracking Status Changed

onCmpUpdateGoogleConsent

Listener for consent mode changes

Import/Export Consent

To import or export the consent you can use the function exportCMPData() and importCMPData(String cmpData). Check the example below: 

// Instanstiate CMPConsentTool()
cmpConsentTool = CMPConsentTool.init(...)

// Importing consent data if you like
cmpConsentTool.importCmpString("${your consentString}");

// ... Your code here ...


// Exporting Consent data 
let consentString : String = CMPConsentTool.exportCmpString()

The consentString you need to pass should be base64 encoded.

CMP SDK Sequence Diagram

In this example we show you three possible SDK sequence flows to understand the consentmanager and there processes. 

1. When creating an instance using the initialize function, there are two possible outcomes. The first is when the consentmanger API informs the SDK that the CMP will not open, which triggers the OnCmpNotOpenedCallback. The second outcome is when the consent layer opens, allowing the user to interact with it, and this triggers the OnOpenCallback. Once the user gives consent and the consent is processed, the OnCmpCloseCallback is called.

Please note that the OnErrorCallback is represented by the red dashed arrow lines to provide examples of when errors may occur during the process.

Initialize-Cmp-Sequence-Diagram.png

2. Creating an instance and calling the openAndCheckConsent functions will lead to a similar process. The difference is that by decoupling the creation of the instance and the check for the consentmanger API, you gain the ability to add business logic and interact with the libraries API.

3. Creating an instance and calling the openLayer function will open the layer without checking the consentmanager, if it's necessary. If there is already given consent, the options and settings will be shown to the user. The process flow will look like this:

openlayer-Cmp-Sequence-Diagram-.png

 

Logging

When using our iOS SDK, you may find the need to debug or analyze log information for various purposes. The logs generated by our SDK are tagged under "CmpConfig", allowing you to easily filter and view only the relevant logs. This guide provides step-by-step instructions on how to access these logs in Xcode.

Search for the Tag

In Xcode's debug console, you can search for logs specifically tagged with "Consent"  or "CMP" to isolate the logs generated by our SDK.

Optional: Adjust Verbose Level

In CmpConfig, you can adjust the verbose level for more detailed logs.

cmpConfig.isDebugMode = true   
cmpConfig.logLevel = CmpLogLevel.debug
  • Enables more detailed logs
  • Useful for debugging and analysis.

By adjusting the verbose level, you can get more comprehensive log information, aiding in debugging and analysis of our SDK's behavior in your application.

 

Back to top