Quantcast Choice allows site owners to manage consent across multiple devices and environments, including iOS. Quantcast Choice Mobile CMP (the CMP) follows the IAB TCF v2 standard. It requires at least iOS 11.0 and greater. The CMP UX is rendered within a view controller presented on top of the rootViewController of the application. All consent data is stored as outlined in the IAB TCF v2 mobile specs using UserDefaults.
The CMP uses native UI components inside a viewController which will be presented on top of the rootViewController.. With our recent release (iOS v1005 and Android v2007) we have added UI customization to our Choice mobile SDK. The UI customization allows the developer to customize color and font styles for all the UI components used in the Choice Mobile CMP, allowing the developer to match the UI style of the host application. For information on how to customize styles, see our UI Customization for Mobile iOS article.
Follow these steps to set up the Choice iOS SDK:
- CMP SDK & Configuration
- Set up Xcode Project
- Integrate Choice for Mobile Apps
- Implement Delegate
- Find Your Account ID
CMP SDK & Configuration
Start in our Choice portal by configuring your app under the general setting in the Protect an App page. Your application’s bundleID must match the Package ID field given here.
After you configure your app in our Choice Configuration Portal, you can download the SDK using the button on the top right of the portal labeled "Download SDK"
Optional: You can also get the SDK using Cocoapods with the pod name: ChoiceMobile,
Set up Xcode Project
From CocoaPods (Recommended):
Simply add the pod to your CocoaPods dependency file: pod ChoiceMobile
From Downloaded zip
1. From your open XCode project, select the top (blue) project file from the left file pane.
2. On the General tab, find the 'Frameworks, Libraries, and Embedded Content' section and click the + button.
3. On the bottom left of the popover, click the 'Add Other…' dropdown and select 'Add Files…', select ChoiceMobile.framework file.
4. Setup simulator to ignore arm64 in the (new to XCode 13+) While still in the Xcode Targets settings, select Build Settings from the top tabs. Select All and find the Exclude Architectures. Add a new section to the Debug row. By default this will say Any SDK which should be changed to Any iOS Simulator SDK. Finally, in the right column type arm64.
From Swift Package Manager (SPM)
1. From your open XCode project, select the very top File menu dropdown select Add Packages.
2. In the top right search field enter "https://github.com/quantcast/choice-mobile-ios" to find Choice Mobile. Select your preferred Dependency Rules. We recommend using Up to Next Major Version starting from 1.0.0 in order to always keep up to date with the latest minor versions. However you can pin to a specific version as well. When done click Add Package in the lower right.
3. Setup simulator to ignore arm64 in the (new to XCode 13+) While still in the Xcode Targets settings, select Build Settings from the top tabs. Select All in the and find the Exclude Architectures Add a new section to the Debug row. By default this will say Any SDK which should be changed to Any iOS Simulator SDK. Finally, in the right column type arm64.
Integrate Choice for Mobile Apps
SDK Integration (Swift)
1. Import import ChoiceMobile into your UIApplicationDelegate class.
import ChoiceMobile
2. Make your delegate class implement the ChoiceCmpDelegate or create separate delegate class. (Note: The ChoiceCmp keeps a weak reference to the delegate object to avoid retain cycles. Make sure you retain a reference somewhere in your code to prevent it from being cleaned up)
class AppDelegate: UIResponder, UIApplicationDelegate, ChoiceCmpDelegate,CCPADelegate {
3. Implement the required callbacks. There is more info on callbacks best practices in the next section.
func didReceiveIABVendorConsent(tcData: TCData, updated:Bool) { }
func didRecieveNonIABVendorConsent(nonIabData: NonIABData, updated:Bool) { }
func didRecieveAdditionalConsent(acData: ACData, updated:Bool) { }
func cmpDidError(error: Error)
func didReceiveCCPAConsent(string: String) { }
4. In your UIApplication delegate's application:didFinishLaunchingWithOptions: method. The method requires a pcode which can be found in the web portal and a delegate which is described below. There is also an optional `shouldDisplayIDFA` which allows you to display the native iOS IDFA permission popup (details) place the following below any rootViewController initialization:
ChoiceCmp.shared.startChoice(pcode: <Quantcast_Pcode_here>, delegate: <ChoiceCmpDelegate>, ccpaDelegate: <CCPADelegate>, shouldDisplayIDFA: true)
5. (Optional) If you set the shouldDisplayIDFA parameter to true, then you must add the `NSUserTrackingUsageDescription` key to your Info.plist and give it a description of what this value will be used for in your app. More details below.
6. Implement a way to force the CMP dialog to show. This is required in order to allow a user to change consent at any time they want. Usually this can be put in a menu next to your apps privacy policy or other settings.
Note: The startChoice method will take care of showing the popup if it is required. This method is only needed to show the popup on demand. To pop open the CMP just call:
ChoiceCmp.shared.forceDisplayUI()
SDK Integration (SwiftUI)
- Import `import ChoiceMobile` into your `App` class
import ChoiceMobile
- Make a simple delegate class that implements the `ChoiceCmpDelegate` at the top of the file or wherever you'd like. (Note: The ChoiceCmp keeps a weak reference to the delegate object to avoid retain cycles. Make sure you retain a reference somewhere in your code to prevent it from being cleaned up)
class ChoiceDelegate: NSObject, ChoiceCmpDelegate, CCPADelegate{
- Implement the required callbacks. More info on callbacks best practices in the next section.
func didReceiveIABVendorConsent(tcData: TCData, updated:Bool) { }
func didRecieveNonIABVendorConsent(nonIabData: NonIABData, updated:Bool) { }
func didReceiveAdditionalConsent(acData: ACData, updated:Bool) {}
func didReceiveCCPAConsent(string: String) { }
func cmpDidError(error: Error)
- Set up an onChange notification of the main WindowGroup, and initialize the CMP on the active state:
.onChange(of: scenePhase) { newScenePhase in
if newScenePhase == .active {
ChoiceCmp.shared.startChoice(pcode: <Quantcast_Pcode_here>, delegate: ChoiceDelegate())
}
}
- (Optional) If you set the shouldDisplayIDFA parameter to true, then you must add the `NSUserTrackingUsageDescription` key to your Info.plist and give it a description of what this value will be used for in your app. More details below.
- Implement a way to force the CMP dialog to show. This is required in order to allow a user to change consent at any time they want. Usually this can be put in a menu next to your app’s privacy policy or other settings. Note: The startChoice method will take care of showing the popup if it is required. This method is only needed to show the popup on demand. To pop open the CMP just call
ChoiceCmp.shared.forceDisplayUI()
SDK Integration (Objective C)
The Choice CMP is also compatible with Objective C. These steps would be required for products using React Native
- Import ChoiceMobile into your `UIApplicationDelegate` header (.h) file
#import<ChoiceMobile/ChoiceMobile-Swift.h>
- Make your delegate class implement the `ChoiceCmpDelegate` or create separate delegate class. (Note: The ChoiceCmp keeps a weak reference to the delegate object to avoid retain cycles. Make sure you retain a reference somewhere in your code to prevent it from being cleaned up)
@interface AppDelegate : UIResponder <UIApplicationDelegate, ChoiceCmpDelegate, CCPADelegate>
>
- Implement the required callbacks. More info best practices in the callbacks in the next section.
- (void)cmpDidErrorWithError:(NSError * _Nonnull)error {}
- (void)cmpDidLoadWithInfo:(PingResponse * _Nonnull)info {}
- (void)cmpDidShowWithInfo:(PingResponse * _Nonnull)info {}
- (void)didReceiveAdditionalConsentWithAcData:(ACData * _Nonnull)acData updated:(BOOL)updated {}
- (void)didReceiveIABVendorConsentWithTcData:(TCData * _Nonnull)tcData updated:(BOOL)updated {}
- (void)didReceiveNonIABVendorConsentWithNonIabData:(NonIABData * _Nonnull)nonIabData updated:(BOOL)updated {}
- (void)didReceiveCCPAConsent:(NSString * _Nonnull)string { }
- In your `UIApplication` delegate's `application:didFinishLaunchingWithOptions:` method, place the following below any rootViewController initialization:
[[ChoiceCmp shared] startChoiceWithPcode:@<Quantcast_Pcode_here>" delegate:<ChoiceDelegateClass>, ccpaDelegate: <ChoiceDelegateClass>)
- (Optional) If you set the shouldDisplayIDFA parameter to true, then you must add the `NSUserTrackingUsageDescription` key to your Info.plist and give it a description of what this value will be used for in your app. More details below.
- Implement a way to force the CMP dialog to show. This is required in order to allow a user to change consent at any time they want. Usually this can be put in a menu next to your app’s privacy policy or other settings. Note: The startChoice method will take care of showing the popup if it is required. This method is only needed to show the popup on demand. To pop open the CMP just call.
[[ChoiceCmp shared] forceDisplayUI]
This is all that is required at this point. The SDK will monitor any lifecycle events and be sure that consent is available. If consent is not found, the CMP will automatically pop up and prompt the user. Every time a user has been prompted the callbacks will fire.
Implement Delegate
You must implement the three different consent callbacks even though you may not have configured all of the consent features. We just want to be sure no consent handling is missed.
1. `didReceiveIABVendorConsent` is called with user consent for IAB compliant vendors. A list of IAB compliant vendors can be found here. Ideally IAB compliant mobile frameworks will automatically pick up this consent and configure themselves on or off. However, there are not many IAB compliant mobile frameworks so if you are in doubt reach out to your vendor and ask. If the framework is not compliant, then you are responsible for handling the consent yourself. If the framework has a setup method that is supposed to be called in the `didFinishLaunchingWithOptions`, that should instead be moved here and called after consent is checked. For example:
func didReceiveIABVendorConsent(tcData: TCData) {
// if GDPR does NOT apply, feel free to start up all your vendors
If !gdprapplies || tcData.vendor.consents[200]{
// start up Quantcast Measure SDK
QuantcastMeasurement.sharedInstance.setupMeasurementSessionWithAPIKey(...)
}
}
2. `didRecieveNonIABVendorConsent` callback. These are vendors that have been set up in the Choice Portal and will not automatically check for consent. Consent is given as a simple "yes, everything" or "no, nothing". To check consent look up the specific vendor by id (given in the Choice Portal) with the following
func didRecieveNonIABVendorConsent(nonIabData: NonIABData) {
if(!nonIabData.gdprApplies || nonIabData.nonIabVendorConsents[vendorID]){
//startup vendor SDK
}else {
//turnoff vendor
}
}
3. The other main callback to be aware of is `didReceiveAdditionalConsent`. This callback is called only if you have Google Vendors turned on in the portal. For more information about Google Vendors please see https://support.google.com/admanager/answer/9681920. Similar to the other callbacks you should use this callback to manage the Google Vendors
func didReceiveAdditionalConsent (acData: ACData) {
if(!acData.gdprApplies || acData.additionalVendorConsent[vendorID]){
//startup vendor SDK
}else {
//turnoff vendor
}
}
The rest of the callbacks are probably not necessary but are provided for debugging or advanced uses. `cmpDidError` will fire any time the CMP exits unexpectedly and fails to collect consent for whatever reason.
CCPA Integration
Once you have initialized the SDK and all the loading process are completed you can show CCPA screen by calling the following method:
ChoiceCmp.shared.startCCPA()
Note: You will need to add a UI control into your application with a text like "Do not sell my data" with an action to launch to CCPA UI to let the user opt out of selling their data.
Then you will be able to get the IABUSPrivacy_String through UserDefaults using the same name as key or through the CCPADelegate function which will be called when the user gives exists the CCPA screen.
func didReceiveCCPAConsent(string: String)
Find Your Account ID
The SDK initialization requires you to pass us your account id (or p-code) for identification. This id can be found on the Choice Portal in the top right corner. Click on the account name and a dropdown will appear with the p-code next to it.
Displaying IDFA Popup
The CMP also allows you to integrate in the new native IDFA permission popup (ATTrackingManager) if the user has given permission to do so in the CMP purposes. We believe showing the popup immediately following the CMP gives user more context into what is being asked for and will result in greater acceptance. The popup will show if GDPR applies and all purpose consents have been given or if GDPR explicitly does NOT apply. If your app and its vendors will never use the IDFA, or you want to display this popup at another time yourself, then this option should be set to false. If this option is set to true, then it is required that you set a usage description in your Info.plist. To do this add a new key called NSUserTrackingUsageDescription and give it short but through description on what the IDFA will be used for. For example "We use this value to help serve you relevant advertising"