GDPR
- It’s mandatory to use a privacy dialog to comply with Play Store and App Store policies and also avoid any revenue loss.
- If you use MAS built-in privacy dialog, GDPR will be configured automatically.
- If you prefer using your own privacy dialog, you should check the users’ age and add an agreement link to get their consent to having their data collected, then set GDPR manually.
- You need to set GDPR before initializing MAS.
What Is GDPR?
The General Data Protection Regulation (GDPR) is a regulation in EU law on data protection and privacy for all individual citizens of the European Union (EU) and the European Economic Area (EEA). For details, check this article.
The most important thing to know is in order to be compliant with GDPR, you need to give users in the EU the choice to opt out of data collection for your game, and players under 16 must also opt out of data collection, as they are below the age of consent.
How to set GDPR
If you have EU users, follow the steps below to comply with GDPR.
Step 1, Determine whether a user is in the EU region
Step 2, Create a pop up window that verifies that the user is over 16 and consents to sharing his data.
Example: We collect player data and distribute it to third parties to personalize the game experience. This personalization leads to a more engaging, and exciting, game play experience. If you are under the age of 16, or do not consent to having your data shared, you may opt out. Also, please make sure to add two options, one for consenting and one for not consenting.
Step 3, Get Authorization Result
If the user is above 16 and indicates consent, use the following methods:
- Unity
- Java
- Kotlin
- Swift
- Objective-C
- React Native
Yodo1U3dMas.SetGDPR(true);
Yodo1Mas.getInstance().setGDPR(true);
Yodo1Mas.getInstance().setGDPR(true);
Yodo1Mas.sharedInstance().isGDPRUserConsent = true
[Yodo1Mas sharedInstance].isGDPRUserConsent = Yes;
Yodo1MASAds.setGDPR(true);
If the user is under 16 or doesn’t consent, use the following methods:
- Unity
- Java
- Kotlin
- Swift
- Objective-C
- React Native
Yodo1U3dMas.SetGDPR(false);
Yodo1Mas.getInstance().setGDPR(false);
Yodo1Mas.getInstance().setGDPR(false);
Yodo1Mas.sharedInstance().isGDPRUserConsent = NO
[Yodo1Mas sharedInstance].isGDPRUserConsent = NO;
Yodo1MASAds.setGDPR(false);
TCF v2.0 Consent
Beginning January 16, 2024, developers accessing Google demands will be required to utilize a Consent Management Platform (CMP) that has been certified by Google and has integrated with the IAB's Transparency and Consent Framework (TCF) when serving ads to users in the European Economic Area or the UK.
If the application fails to adopt a Google-certified CMP, only limited ads will be eligible to serve on EEA and UK traffic. However, traffic from a Google-certified CMP will continue to be eligible for personalized ads, non-personalized ads (NPA), or limited ads.
The MAS SDK has integrated Google's consent management solution, the UMP SDK, and has automatically configured GDPR messages for applications that have EEA and UK users. With the MAS SDK, the GDPR consent form will be intuitively presented to collect consent from EEA and UK users starting from their second launch.
If you wish to activate the UMP SDK from the initial launch, please utilize the following methods:
- Unity
- Java
- Kotlin
- Swift
- Objective-C
- React Native
Yodo1AdBuildConfig config = new Yodo1AdBuildConfig()
.enableUserMessageingPlatform(Yodo1MasUMPState.ENABLE);
Yodo1U3dMas.SetAdBuildConfig(config);
Yodo1MasAdBuildConfig config = new Yodo1MasAdBuildConfig.Builder()
.enableUserMessageingPlatform(Yodo1MasAdBuildConfig.UMPState.ENABLE)
.build();
Yodo1Mas.getInstance().setAdBuildConfig(config);
val config = Yodo1MasAdBuildConfig.Builder()
.enableUserMessageingPlatform(Yodo1MasAdBuildConfig.UMPState.ENABLE)
.build()
Yodo1Mas.getInstance().setAdBuildConfig(config)
var config = Yodo1MasAdBuildConfig.instance()
config.enableUserMessageingPlatform = .enable
Yodo1Mas.sharedInstance().setAdBuildConfig(config)
Yodo1MasAdBuildConfig *config = [Yodo1MasAdBuildConfig instance];
config.enableUserMessageingPlatform = Yodo1MasUMPStateEnable;
[[Yodo1Mas sharedInstance] setAdBuildConfig:config];
// Not allowed for React Native
If you collaborate with a different CMP solution or if your application does not include users from the EEA and the UK, you can choose to deactivate the UMP SDK by incorporating the following methods:
- Unity
- Java
- Kotlin
- Swift
- Objective-C
- React Native
Yodo1AdBuildConfig config = new Yodo1AdBuildConfig()
.enableUserMessageingPlatform(Yodo1MasUMPState.DISABLE);
Yodo1U3dMas.SetAdBuildConfig(config);
Yodo1MasAdBuildConfig config = new Yodo1MasAdBuildConfig.Builder()
.enableUserMessageingPlatform(Yodo1MasAdBuildConfig.UMPState.DISABLE)
.build();
Yodo1Mas.getInstance().setAdBuildConfig(config);
val config = Yodo1MasAdBuildConfig.Builder()
.enableUserMessageingPlatform(Yodo1MasAdBuildConfig.UMPState.DISABLE)
.build()
Yodo1Mas.getInstance().setAdBuildConfig(config)
var config = Yodo1MasAdBuildConfig.instance()
config.enableUserMessageingPlatform = .diasble
Yodo1Mas.sharedInstance().setAdBuildConfig(config)
Yodo1MasAdBuildConfig *config = [Yodo1MasAdBuildConfig instance];
config.enableUserMessageingPlatform = Yodo1MasUMPStateDisable;
[[Yodo1Mas sharedInstance] setAdBuildConfig:config];
// Not allowed for React Native
Show GDPR Flow to Existing Users
MAS recommends that you allow existing users in GDPR regions to reenter the GDPR flow. Typically, users do this in your app’s Settings section via an option to Manage Existing Privacy Settings. If a user is within a GDPR region you can conditionally show that settings option. To determine this, use the below SDK API:
- Unity
- Java
- Kotlin
- Swift
- Objective-C
- React Native
bool isGdprGeography = (Yodo1U3dMas.GetSdkConfiguration() != null &&
Yodo1U3dMas.GetSdkConfiguration().ConsentFlowUserGeography == Yodo1MasConsentFlowUserGeography.Gdpr);
if (isGdprGeography) {
Yodo1U3dMas.ShowUmpForExistingUser();
}
if (Yodo1Mas.getInstance().getConfiguration() != null &&
Yodo1Mas.getInstance().getConfiguration().getConsentFlowUserGeography() == Yodo1MasSdkConfiguration.Yodo1MasConsentFlowUserGeography.GDPR) {
Yodo1Mas.getInstance().showUmpForExistingUser(MainActivity.this, new OnUmpCompletedListener() {
@Override
public void onCompleted(Yodo1MasUmpError cmpError) {
if (cmpError == null) {
// The UMP alert was shown successfully.
}
}
});
}
if (Yodo1Mas.getInstance().configuration != null &&
Yodo1Mas.getInstance().configuration.consentFlowUserGeography == Yodo1MasSdkConfiguration.Yodo1MasConsentFlowUserGeography.GDPR
) {
Yodo1Mas.getInstance().showUmpForExistingUser(this@MainActivity) { cmpError ->
if (cmpError == null) {
// The UMP alert was shown successfully.
}
}
}
let isGdprGeography = Yodo1Mas.sharedInstance().configuration.consentFlowUserGeography == .gdpr
if (isGdprGeography) {
Yodo1Mas.sharedInstance().showUmp { error in
if (error == nil) {
// The UMP alert was shown successfully.
}
}
}
BOOL isGdprGeography = [[Yodo1Mas sharedInstance] configuration] != nil &&
[[Yodo1Mas sharedInstance] configuration].consentFlowUserGeography == Yodo1MasConsentFlowUserGeographyGdpr;
if (isGdprGeography) {
[[Yodo1Mas sharedInstance] showUmpForExistingUser:^(Yodo1MasError * _Nullable error) {
if (error == nil) {
// The UMP alert was shown successfully.
}
}];
}
// Not allowed for React Native
How to read consent choices
After GDPR consent has been collected, you can read consent choices from local storage following the TCF v2 spec. The IABTCF_PurposeConsents
key indicates consent for each of the TCF purposes.
The following code snippet shows how to check consent for Purpose 1:
- Unity
- Java
- Kotlin
- Swift
- Objective-C
- React Native
// Example value: "1111111111"
string purposeConsents = Yodo1U3dMas.GetIABTCFString("IABTCF_PurposeConsents");
// Purposes are zero-indexed. Index 0 contains information about Purpose 1.
if (!string.IsNullOrEmpty(purposeConsents))
{
char purposeOneString = purposeConsents[0];
bool hasConsentForPurposeOne = purposeOneString == '1';
}
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
// Example value: "1111111111"
String purposeConsents = sharedPref.getString("IABTCF_PurposeConsents", "");
// Purposes are zero-indexed. Index 0 contains information about Purpose 1.
if (!purposeConsents.isEmpty()) {
String purposeOneString = purposeConsents.charAt(0);
boolean hasConsentForPurposeOne = purposeOneString.equals("1");
}
val sharedPref = PreferenceManager.getDefaultSharedPreferences(context)
// Example value: "1111111111"
val purposesConsents = sharedPref.getString("IABTCF_PurposeConsents", "")
// Purposes are zero-indexed. Index 0 contains information about Purpose 1.
if (!purposeConsents.isEmpty()) {
val purposeOneString = purposeConsents.first()
val hasConsentForPurposeOne = purposeOneString == "1"
}
// Example value: "1111111111"
let purposeConsents = UserDefaults.standard.string(forKey: "IABTCF_PurposeConsents")
// Purposes are zero-indexed. Index 0 contains information about Purpose 1.
let hasConsentForPurposeOne = purposeConsents?.first == "1"
// Example value: "1111111111"
NSString *purposeConsents = [NSUserDefaults.standardUserDefaults
stringForKey:@"IABTCF_PurposeConsents"];
// Purposes are zero-indexed. Index 0 contains information about Purpose 1.
BOOL hasConsentForPurposeOne = [purposeConsents hasPrefix:@"1"];
// Not allowed for React Native