From db70d94c06edeb9a93494be3826a3d6e881ce733 Mon Sep 17 00:00:00 2001 From: Dmytro Date: Wed, 6 Mar 2024 19:52:42 +0200 Subject: [PATCH 01/10] DIA-3630 Add wrapper for android `usnat` --- .../Scripts/facade/CMP.cs | 1 - .../android/SpConsentsWrapperAndroid.cs | 1 + .../wrappers/android/SpUsnatConsentWrapper.cs | 31 +++++++++++++++++++ .../android/SpUsnatConsentWrapper.cs.meta | 11 +++++++ .../json/wrappers/ios/UsnatConsentWrapper.cs | 6 ++-- .../Scripts/model/common/UsnatConsent.cs | 25 +++++++++++++-- 6 files changed, 69 insertions(+), 6 deletions(-) create mode 100644 Assets/ConsentManagementProvider/Scripts/json/wrappers/android/SpUsnatConsentWrapper.cs create mode 100644 Assets/ConsentManagementProvider/Scripts/json/wrappers/android/SpUsnatConsentWrapper.cs.meta diff --git a/Assets/ConsentManagementProvider/Scripts/facade/CMP.cs b/Assets/ConsentManagementProvider/Scripts/facade/CMP.cs index c39a7c40..b27e2f25 100644 --- a/Assets/ConsentManagementProvider/Scripts/facade/CMP.cs +++ b/Assets/ConsentManagementProvider/Scripts/facade/CMP.cs @@ -51,7 +51,6 @@ public static void Initialize( { return; } - //TO-DO add usnat ConsentWrapperAndroid.Instance.InitializeLib( spCampaigns: spCampaigns, accountId: accountId, diff --git a/Assets/ConsentManagementProvider/Scripts/json/wrappers/android/SpConsentsWrapperAndroid.cs b/Assets/ConsentManagementProvider/Scripts/json/wrappers/android/SpConsentsWrapperAndroid.cs index 70450443..fc058ccc 100644 --- a/Assets/ConsentManagementProvider/Scripts/json/wrappers/android/SpConsentsWrapperAndroid.cs +++ b/Assets/ConsentManagementProvider/Scripts/json/wrappers/android/SpConsentsWrapperAndroid.cs @@ -5,6 +5,7 @@ internal class SpConsentsWrapperAndroid #nullable enable public CcpaConsentWrapper? ccpa; public SpGdprConsentWrapperAndroid? gdpr; + public SpUsnatConsentWrapperAndroid? usnat; #nullable disable } } \ No newline at end of file diff --git a/Assets/ConsentManagementProvider/Scripts/json/wrappers/android/SpUsnatConsentWrapper.cs b/Assets/ConsentManagementProvider/Scripts/json/wrappers/android/SpUsnatConsentWrapper.cs new file mode 100644 index 00000000..7974e296 --- /dev/null +++ b/Assets/ConsentManagementProvider/Scripts/json/wrappers/android/SpUsnatConsentWrapper.cs @@ -0,0 +1,31 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace ConsentManagementProviderLib.Json +{ + internal class SpUsnatConsentWrapperAndroid + { +#nullable enable + public string? uuid; +#nullable disable + public StatusWrapperAndroid statuses; + public bool applies; + public string consentStrings; + public string vendors; + public string categories; + } + + internal class StatusWrapperAndroid + { +#nullable enable + public bool? hasConsentData; + public bool? rejectedAny; + public bool? consentedToAll; + public bool? consentedToAny; + public bool? sellStatus; + public bool? shareStatus; + public bool? sensitiveDataStatus; + public bool? gpcStatus; +#nullable disable + } +} diff --git a/Assets/ConsentManagementProvider/Scripts/json/wrappers/android/SpUsnatConsentWrapper.cs.meta b/Assets/ConsentManagementProvider/Scripts/json/wrappers/android/SpUsnatConsentWrapper.cs.meta new file mode 100644 index 00000000..124df77c --- /dev/null +++ b/Assets/ConsentManagementProvider/Scripts/json/wrappers/android/SpUsnatConsentWrapper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f556f319fb429e143a9af4621869fa7b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ConsentManagementProvider/Scripts/json/wrappers/ios/UsnatConsentWrapper.cs b/Assets/ConsentManagementProvider/Scripts/json/wrappers/ios/UsnatConsentWrapper.cs index 2d1155a9..ca4f9ec0 100644 --- a/Assets/ConsentManagementProvider/Scripts/json/wrappers/ios/UsnatConsentWrapper.cs +++ b/Assets/ConsentManagementProvider/Scripts/json/wrappers/ios/UsnatConsentWrapper.cs @@ -28,15 +28,17 @@ internal class UserConsentsWrapper internal class ConsentableWrapper { +#if UNITY_IOS && !UNITY_EDITOR_OSX [JsonProperty("_id")] +#endif public string id; public bool consented; } internal class ConsentStringWrapper { - public string consentString; - public string sectionId; + public int sectionId; public string sectionName; + public string consentString; } } \ No newline at end of file diff --git a/Assets/ConsentManagementProvider/Scripts/model/common/UsnatConsent.cs b/Assets/ConsentManagementProvider/Scripts/model/common/UsnatConsent.cs index a707974f..6ef7cd5f 100644 --- a/Assets/ConsentManagementProvider/Scripts/model/common/UsnatConsent.cs +++ b/Assets/ConsentManagementProvider/Scripts/model/common/UsnatConsent.cs @@ -32,7 +32,26 @@ ConsentStatus consentStatus this.categories = categories; this.statuses = StatusesUsnat.collectData(consentStatus); } - + + public UsnatConsent( +#nullable enable + string? uuid, + bool applies, + List consentStrings, + List vendors, + List categories, + StatusesUsnat statuses +#nullable disable +) + { + this.uuid = uuid; + this.applies = applies; + this.consentStrings = consentStrings; + this.vendors = vendors; + this.categories = categories; + this.statuses = statuses; + } + public string ToFullString() { StringBuilder sb = new StringBuilder(); @@ -113,10 +132,10 @@ public class Consentable public class ConsentString { public string consentString; - public string sectionId; + public int sectionId; public string sectionName; - public ConsentString(string consentString, string sectionId, string sectionName) + public ConsentString(string consentString, int sectionId, string sectionName) { this.consentString = consentString; this.sectionId = sectionId; From b037c211eead9a41c42f0d47a6e0e7c0f2561ec7 Mon Sep 17 00:00:00 2001 From: Dmytro Date: Wed, 6 Mar 2024 19:54:26 +0200 Subject: [PATCH 02/10] DIA-3630 Update `ConstructCampaignType` --- .../Scripts/wrapper/Android/AndroidJavaConstruct.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Assets/ConsentManagementProvider/Scripts/wrapper/Android/AndroidJavaConstruct.cs b/Assets/ConsentManagementProvider/Scripts/wrapper/Android/AndroidJavaConstruct.cs index 8ce166f1..5e3e2633 100644 --- a/Assets/ConsentManagementProvider/Scripts/wrapper/Android/AndroidJavaConstruct.cs +++ b/Assets/ConsentManagementProvider/Scripts/wrapper/Android/AndroidJavaConstruct.cs @@ -67,6 +67,9 @@ internal AndroidJavaObject ConstructCampaignType(CAMPAIGN_TYPE campaignType) case CAMPAIGN_TYPE.CCPA: type = enumClass.GetStatic("CCPA"); break; + case CAMPAIGN_TYPE.USNAT: + type = enumClass.GetStatic("USNAT"); + break; default: CmpDebugUtil.LogError("CampaignType is NULL. How did you get there?"); break; From 8d090bdd25c2f4abcdb8bc0d7c446a8675c7835c Mon Sep 17 00:00:00 2001 From: Dmytro Date: Wed, 6 Mar 2024 19:56:47 +0200 Subject: [PATCH 03/10] DIA-3630 Add parse method for `usnat` --- .../Scripts/json/JsonUnwrapper.cs | 44 ++++++++++++++++++- .../Scenes/SourcepointSampleScene.unity | 2 +- Assets/ExampleApp/Scripts/PrivacySettings.cs | 2 +- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/Assets/ConsentManagementProvider/Scripts/json/JsonUnwrapper.cs b/Assets/ConsentManagementProvider/Scripts/json/JsonUnwrapper.cs index 2471c8fe..8f4c4051 100644 --- a/Assets/ConsentManagementProvider/Scripts/json/JsonUnwrapper.cs +++ b/Assets/ConsentManagementProvider/Scripts/json/JsonUnwrapper.cs @@ -25,12 +25,13 @@ public static SpConsents UnwrapSpConsentsAndroid(string json) SpGdprConsent unwrappedGdpr = CMP.useGDPR ? UnwrapSpGdprConsentAndroid(wrapped.gdpr) : null; SpCcpaConsent unwrappedCcpa = CMP.useCCPA ? UnwrapSpCcpaConsentAndroid(wrapped.ccpa) : null; - SpUsnatConsent unwrappedUsnat = CMP.useUSNAT ? null : null; //TODO parse + SpUsnatConsent unwrappedUsnat = CMP.useUSNAT ? UnwrapSpUsnatConsentAndroid(wrapped.usnat) : null; return new SpConsents(unwrappedGdpr, unwrappedCcpa, unwrappedUsnat); } catch (NewtonsoftJson.JsonException ex) { + CmpDebugUtil.LogError(ex.Message); throw new ApplicationException("Error deserializing JSON.", ex); } catch (Exception ex) @@ -39,6 +40,47 @@ public static SpConsents UnwrapSpConsentsAndroid(string json) } } + private static SpUsnatConsent UnwrapSpUsnatConsentAndroid(SpUsnatConsentWrapperAndroid wrapped) + { + StatusesUsnat _statuses = new StatusesUsnat + { + hasConsentData = wrapped.statuses.hasConsentData, + rejectedAny = wrapped.statuses.rejectedAny, + consentedToAll = wrapped.statuses.consentedToAll, + consentedToAny = wrapped.statuses.consentedToAny, + sellStatus = wrapped.statuses.sellStatus, + shareStatus = wrapped.statuses.shareStatus, + sensitiveDataStatus = wrapped.statuses.sensitiveDataStatus, + gpcStatus = wrapped.statuses.gpcStatus + }; + List _consentStrings = new List(); + List _consentStringsWrapped = NewtonsoftJson.JsonConvert.DeserializeObject>(wrapped.consentStrings); + foreach (ConsentStringWrapper _string in _consentStringsWrapped) + { + _consentStrings.Add(new ConsentString(_string.consentString, _string.sectionId, _string.sectionName)); + } + + List _vendors = new List(); + List _vendorsWrapped = NewtonsoftJson.JsonConvert.DeserializeObject>(wrapped.vendors); + foreach (ConsentableWrapper _consentable in _vendorsWrapped) + { + _vendors.Add(new Consentable { id = _consentable.id, consented = _consentable.consented }); + } + + List _categories = new List(); + List _categoriesWrapped = NewtonsoftJson.JsonConvert.DeserializeObject>(wrapped.categories); + foreach (ConsentableWrapper _consentable in _categoriesWrapped) + { + _categories.Add(new Consentable { id = _consentable.id, consented = _consentable.consented }); + } + return new SpUsnatConsent(new UsnatConsent(uuid: wrapped.uuid, + applies: wrapped.applies, + consentStrings: _consentStrings, + vendors: _vendors, + categories: _categories, + statuses: _statuses)); + } + private static SpCcpaConsent UnwrapSpCcpaConsentAndroid(CcpaConsentWrapper wrappedCcpa) { if (wrappedCcpa == null) diff --git a/Assets/ExampleApp/Scenes/SourcepointSampleScene.unity b/Assets/ExampleApp/Scenes/SourcepointSampleScene.unity index a6e36b69..4406cc7f 100644 --- a/Assets/ExampleApp/Scenes/SourcepointSampleScene.unity +++ b/Assets/ExampleApp/Scenes/SourcepointSampleScene.unity @@ -237,7 +237,7 @@ MonoBehaviour: propertyId: 16893 propertyName: mobile.multicampaign.demo useGDPR: 1 - useCCPA: 0 + useCCPA: 1 useUSNAT: 1 gdprPmId: 488393 ccpaPmId: 509688 diff --git a/Assets/ExampleApp/Scripts/PrivacySettings.cs b/Assets/ExampleApp/Scripts/PrivacySettings.cs index c62297a5..99be1d59 100644 --- a/Assets/ExampleApp/Scripts/PrivacySettings.cs +++ b/Assets/ExampleApp/Scripts/PrivacySettings.cs @@ -67,7 +67,7 @@ private void Awake() if (useUSNAT) { List usnatParams = new List { new TargetingParam("location", "US") }; - SpCampaign usnat = new SpCampaign(CAMPAIGN_TYPE.CCPA, usnatParams); + SpCampaign usnat = new SpCampaign(CAMPAIGN_TYPE.USNAT, usnatParams); spCampaigns.Add(usnat); } From e6a0f089f98c7789d69410fbbbd046609c912912 Mon Sep 17 00:00:00 2001 From: Dmytro Date: Wed, 6 Mar 2024 19:57:42 +0200 Subject: [PATCH 04/10] DIA-3630 Update `dependencies` to `7.8.0` for android --- .../Editor/SourcepointDependencies.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/ExternalDependencyManager/Editor/SourcepointDependencies.xml b/Assets/ExternalDependencyManager/Editor/SourcepointDependencies.xml index a16f7bb0..156a0e06 100644 --- a/Assets/ExternalDependencyManager/Editor/SourcepointDependencies.xml +++ b/Assets/ExternalDependencyManager/Editor/SourcepointDependencies.xml @@ -39,6 +39,6 @@ - + From 3bdb652bce186be17dbe01c8965d6dba68453900 Mon Sep 17 00:00:00 2001 From: Dmytro Date: Fri, 8 Mar 2024 19:59:33 +0200 Subject: [PATCH 05/10] DIA-3630 Add `transitionCCPAAuth` and `supportLegacyUSPString` --- .../Scripts/enum/Android/CONFIG_OPTION.cs | 9 ++++++++ .../enum/Android/CONFIG_OPTION.cs.meta | 11 ++++++++++ .../Scripts/facade/CMP.cs | 4 +++- .../wrapper/Android/AndroidJavaConstruct.cs | 22 +++++++++++++++++++ .../wrapper/Android/CmpJavaToUnityUtils.cs | 10 +++++++++ .../wrapper/Android/ConsentWrapperAndroid.cs | 8 +++++-- 6 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 Assets/ConsentManagementProvider/Scripts/enum/Android/CONFIG_OPTION.cs create mode 100644 Assets/ConsentManagementProvider/Scripts/enum/Android/CONFIG_OPTION.cs.meta diff --git a/Assets/ConsentManagementProvider/Scripts/enum/Android/CONFIG_OPTION.cs b/Assets/ConsentManagementProvider/Scripts/enum/Android/CONFIG_OPTION.cs new file mode 100644 index 00000000..96cad761 --- /dev/null +++ b/Assets/ConsentManagementProvider/Scripts/enum/Android/CONFIG_OPTION.cs @@ -0,0 +1,9 @@ +namespace ConsentMessagePlugin.Android +{ + internal static class CONFIG_OPTION_FULL_KEY + { + internal const string + TRANSITION_CCPA_AUTH = "TRANSITION_CCPA_AUTH", + SUPPORT_LEGACY_USPSTRING = "SUPPORT_LEGACY_USPSTRING"; + } +} \ No newline at end of file diff --git a/Assets/ConsentManagementProvider/Scripts/enum/Android/CONFIG_OPTION.cs.meta b/Assets/ConsentManagementProvider/Scripts/enum/Android/CONFIG_OPTION.cs.meta new file mode 100644 index 00000000..d3297d25 --- /dev/null +++ b/Assets/ConsentManagementProvider/Scripts/enum/Android/CONFIG_OPTION.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 21f6dc21f0fe1b749935bb0e0ce4253f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/ConsentManagementProvider/Scripts/facade/CMP.cs b/Assets/ConsentManagementProvider/Scripts/facade/CMP.cs index b27e2f25..9d2624e2 100644 --- a/Assets/ConsentManagementProvider/Scripts/facade/CMP.cs +++ b/Assets/ConsentManagementProvider/Scripts/facade/CMP.cs @@ -58,7 +58,9 @@ public static void Initialize( propertyName: propertyName, language: language, campaignsEnvironment: campaignsEnvironment, - messageTimeoutMilliSeconds: messageTimeoutInSeconds * 1000); + messageTimeoutMilliSeconds: messageTimeoutInSeconds * 1000, + transitionCCPAAuth: transitionCCPAAuth, + supportLegacyUSPString: supportLegacyUSPString); #elif UNITY_IOS && !UNITY_EDITOR_OSX CreateBroadcastExecutorGO(); diff --git a/Assets/ConsentManagementProvider/Scripts/wrapper/Android/AndroidJavaConstruct.cs b/Assets/ConsentManagementProvider/Scripts/wrapper/Android/AndroidJavaConstruct.cs index 5e3e2633..542d0e72 100644 --- a/Assets/ConsentManagementProvider/Scripts/wrapper/Android/AndroidJavaConstruct.cs +++ b/Assets/ConsentManagementProvider/Scripts/wrapper/Android/AndroidJavaConstruct.cs @@ -1,5 +1,7 @@ using ConsentManagementProviderLib.Enum; using ConsentMessagePlugin.Android; +using System.Collections.Generic; +using System.Linq; using UnityEngine; namespace ConsentManagementProviderLib.Android @@ -55,6 +57,26 @@ internal AndroidJavaObject ConstructCampaign(AndroidJavaObject campaignType, And return campaign; } + internal AndroidJavaObject ConstructCampaign(AndroidJavaObject campaignType, AndroidJavaObject targetingParams, CAMPAIGN_TYPE campaignTypeForLog, bool? transitionCCPAAuth = null, bool? supportLegacyUSPString = null) + { + AndroidJavaObject[] configOptions = new AndroidJavaObject[2]; + AndroidJavaClass enumConfigOption = new AndroidJavaClass("com.sourcepoint.cmplibrary.creation.ConfigOption"); + if (transitionCCPAAuth.HasValue && transitionCCPAAuth==true) + { + AndroidJavaObject option = enumConfigOption.GetStatic(CONFIG_OPTION_FULL_KEY.TRANSITION_CCPA_AUTH); + configOptions.Append(option); + } + if (supportLegacyUSPString.HasValue && supportLegacyUSPString==true) + { + AndroidJavaObject option = enumConfigOption.GetStatic(CONFIG_OPTION_FULL_KEY.SUPPORT_LEGACY_USPSTRING); + configOptions.Append(option); + } + AndroidJavaObject configSet = CmpJavaToUnityUtils.ConvertArrayToSet(configOptions); + AndroidJavaObject campaign = new AndroidJavaObject("com.sourcepoint.cmplibrary.model.exposed.SpCampaign", campaignType, targetingParams, configSet); + CmpDebugUtil.Log($"Campaign {campaignTypeForLog} with configOptions is OK"); + return campaign; + } + internal AndroidJavaObject ConstructCampaignType(CAMPAIGN_TYPE campaignType) { AndroidJavaObject type = null; diff --git a/Assets/ConsentManagementProvider/Scripts/wrapper/Android/CmpJavaToUnityUtils.cs b/Assets/ConsentManagementProvider/Scripts/wrapper/Android/CmpJavaToUnityUtils.cs index fba2ac46..c4a2483d 100644 --- a/Assets/ConsentManagementProvider/Scripts/wrapper/Android/CmpJavaToUnityUtils.cs +++ b/Assets/ConsentManagementProvider/Scripts/wrapper/Android/CmpJavaToUnityUtils.cs @@ -17,6 +17,16 @@ internal static AndroidJavaObject ConvertArrayToList(AndroidJavaObject[] array) } } + internal static AndroidJavaObject ConvertArrayToSet(AndroidJavaObject[] array) + { + using (AndroidJavaClass UnityUtils = new AndroidJavaClass(UnityUtilsPackageName)) + { + CmpDebugUtil.Log("C# : passing Array to Set conversion to Android's UnityUtils..."); + AndroidJavaObject set = UnityUtils.CallStatic("arrayToSet", new AndroidJavaObject[][] { array }); + return set; + } + } + internal static Exception ConvertThrowableToError(AndroidJavaObject rawErr) { using (AndroidJavaClass UnityUtils = new AndroidJavaClass(UnityUtilsPackageName)) diff --git a/Assets/ConsentManagementProvider/Scripts/wrapper/Android/ConsentWrapperAndroid.cs b/Assets/ConsentManagementProvider/Scripts/wrapper/Android/ConsentWrapperAndroid.cs index 331a1601..9fa0fe69 100644 --- a/Assets/ConsentManagementProvider/Scripts/wrapper/Android/ConsentWrapperAndroid.cs +++ b/Assets/ConsentManagementProvider/Scripts/wrapper/Android/ConsentWrapperAndroid.cs @@ -45,7 +45,7 @@ private set #endif } - public void InitializeLib(List spCampaigns, int accountId, int propertyId, string propertyName, MESSAGE_LANGUAGE language, CAMPAIGN_ENV campaignsEnvironment, long messageTimeoutMilliSeconds = 3000) + public void InitializeLib(List spCampaigns, int accountId, int propertyId, string propertyName, MESSAGE_LANGUAGE language, CAMPAIGN_ENV campaignsEnvironment, long messageTimeoutMilliSeconds = 3000, bool? transitionCCPAAuth = null, bool? supportLegacyUSPString = null) { #if UNITY_ANDROID if (Application.platform == RuntimePlatform.Android) @@ -64,7 +64,11 @@ public void InitializeLib(List spCampaigns, int accountId, int prope paramsArray[sp.TargetingParams.IndexOf(tp)] = param; } AndroidJavaObject paramsList = CmpJavaToUnityUtils.ConvertArrayToList(paramsArray); - AndroidJavaObject campaign = constructor.ConstructCampaign(typeAJO, paramsList, sp.CampaignType); + AndroidJavaObject campaign; + if (sp.CampaignType == CAMPAIGN_TYPE.USNAT && (transitionCCPAAuth.HasValue || supportLegacyUSPString.HasValue)) + campaign = constructor.ConstructCampaign(typeAJO, paramsList, sp.CampaignType, transitionCCPAAuth, supportLegacyUSPString); + else + campaign = constructor.ConstructCampaign(typeAJO, paramsList, sp.CampaignType); campaigns[spCampaigns.IndexOf(sp)] = campaign; } AndroidJavaObject spConfig = constructor.ConstructSpConfig(accountId: accountId, From 0627d94260eeb73ae22870fa048e9ac57e86a026 Mon Sep 17 00:00:00 2001 From: Dmytro Date: Tue, 12 Mar 2024 18:08:15 +0100 Subject: [PATCH 06/10] DIA-3630 Update `README.md` --- README.md | 63 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 2a334f35..cf40c69d 100644 --- a/README.md +++ b/README.md @@ -28,27 +28,47 @@ Construct `List` which contains `SpCampaign` objects. Each `SpCampai SpCampaign ccpa = new SpCampaign(CAMPAIGN_TYPE.CCPA, ccpaParams); spCampaigns.Add(ccpa); - List ios14Params = new List(); - SpCampaign ios14 = new SpCampaign(CAMPAIGN_TYPE.IOS14, ios14Params); - spCampaigns.Add(ios14); + List usnatParams = new List { new TargetingParam("location", "US") }; + SpCampaign usnat = new SpCampaign(CAMPAIGN_TYPE.USNAT, usnatParams); + spCampaigns.Add(usnat); ``` -In order to instantiate & trigger `Consent Message Web View`, you must call the `CMP.Initialize` function in `Awake` along with `spCampaigns`, `accountId`, `propertyId`, `propertyName`, `gdpr`, `ccpa`(allows using campains),`gdprPmId`, `ccpaPmId` and `language`.

Additionally, you can also specify a `messageTimeout` which, by default, is set to **30 seconds**. +In order to instantiate & trigger `Consent Message Web View`, you must call the `CMP.Initialize` function in `Awake` along with `spCampaigns`, `accountId`, `propertyId`, `propertyName`, `gdpr`, `ccpa`, `usnat`,`gdprPmId`, `ccpaPmId`, `usnatPmId` and `language`.

Additionally, you can also specify a `messageTimeout` which, by default, is set to **30 seconds**. ```c# CMP.Initialize(spCampaigns: spCampaigns, accountId: 22, - propertyId: 16893, + propertyId: 16893, propertyName: "mobile.multicampaign.demo", gdpr: true, ccpa: true, + usnat: true, language: MESSAGE_LANGUAGE.ENGLISH, gdprPmId: "488393", ccpaPmId: "509688", + usnatPmId: "943886", campaignsEnvironment: CAMPAIGN_ENV.PUBLIC, - messageTimeoutInSeconds: 30); + messageTimeoutInSeconds: 30, + transitionCCPAAuth: false, + supportLegacyUSPString: false); ``` +| Field | **Description** | +| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `spCampaigns` | List with campaigns launched on the property through the Sourcepoint portal | +| `accountId` | Organization's account ID found in the Sourcepoint portal | +| `propertyId` | ID for property found in the Sourcepoint portal | +| `propertyName` | Name of property found in the Sourcepoint portal | +| `gdpr` | Allows using `gdpr` campaign | +| `ccpa` | Allows using `ccpa` campaign | +| `usnat` | Allows using `usnat` campaign | +| `language` | Force a message to be displayed in a certain language. Look `MESSAGE_LANGUAGE` for all available languages | +| `gdprPmId` | Id of the privacy manager for `gdpr` campaign | +| `ccpaPmId` | Id of the privacy manager for `ccpa` campaign | +| `usnatPmId` | Id of the privacy manager for `usnat` campaign | +| `transitionCCPAAuth` | Transfer opt-in/opt out preferences from U.S. Privacy (Legacy) to U.S. Multi-State Privacy [ios](https://github.com/SourcePointUSA/ios-cmp-app?tab=readme-ov-file#transfer-opt-inopt-out-preferences-from-us-privacy-legacy-to-us-multi-state-privacy), [android](https://github.com/SourcePointUSA/android-cmp-app?tab=readme-ov-file#transfer-opt-inopt-out-preferences-from-us-privacy-legacy-to-us-multi-state-privacy) | +| `supportLegacyUSPString` | Support U.S. Privacy (Legacy) with U.S. Multi-State Privacy [ios](https://github.com/SourcePointUSA/ios-cmp-app?tab=readme-ov-file#support-us-privacy-legacy-with-us-multi-state-privacy) | + > **Note**: It may take a frame to initialize the CMP library, so we strongly recommend that you `Initialize` in `Awake` separately from `LoadMessage`. We recommend that you `LoadMessage` in `Start` (see example below). When the SDK receives the `LoadMessage` call, it will instantiate a webview if the end-user needs to see a message.

If there is a consent profile associated with `authId`, the SDK will bring the consent data from the server, overwriting whatever was stored in the device. @@ -255,16 +275,33 @@ This getter is used to retrieve `SpConsents` data. After calling, it checks the | |-- adUserData: SPGCMData.Status? | |-- adPersonalization: SPGCMData.Status? |-- ccpa? + | |-- applies: bool + | |-- consents: CcpaConsent + | |-- uuid: String? + | |-- rejectedCategories: List + | |-- rejectedVendors: List + | |-- status: String? + | |-- uspstring: String + | |-- childPmId: String + | |-- signedLspa: bool + | |-- consentStatus: ConsentStatus? + |-- usnat? |-- applies: bool |-- consents: CcpaConsent |-- uuid: String? - |-- rejectedCategories: List - |-- rejectedVendors: List - |-- status: String? - |-- uspstring: String - |-- childPmId: String - |-- signedLspa: bool - |-- consentStatus: ConsentStatus? + |-- applies: bool + |-- consentStrings: List + |-- vendors: List //[{id: String, consented: bool }] + |-- categories: List //[{id: String, consented: bool }] + |-- statuses: StatusesUsnat + |-- rejectedAny: bool? + |-- consentedToAll: bool? + |-- consentedToAny: bool? + |-- hasConsentData: bool? + |-- sellStatus: bool? + |-- shareStatus: bool? + |-- sensitiveDataStatus: bool? + |-- gpcStatus: bool? ``` This method may return null. Sample usage: From 21f68b0fe8d8d3694d01bf252f0bc2aa9e8ea17e Mon Sep 17 00:00:00 2001 From: Dmytro Date: Fri, 15 Mar 2024 17:30:09 +0200 Subject: [PATCH 07/10] Update `README.md` --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cf40c69d..13044150 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,10 @@ Construct `List` which contains `SpCampaign` objects. Each `SpCampai SpCampaign ccpa = new SpCampaign(CAMPAIGN_TYPE.CCPA, ccpaParams); spCampaigns.Add(ccpa); + List ios14Params = new List(); + SpCampaign ios14 = new SpCampaign(CAMPAIGN_TYPE.IOS14, ios14Params); + spCampaigns.Add(ios14); + List usnatParams = new List { new TargetingParam("location", "US") }; SpCampaign usnat = new SpCampaign(CAMPAIGN_TYPE.USNAT, usnatParams); spCampaigns.Add(usnat); @@ -38,7 +42,7 @@ In order to instantiate & trigger `Consent Message Web View`, you must call the ```c# CMP.Initialize(spCampaigns: spCampaigns, accountId: 22, - propertyId: 16893, + propertyId: 16893, propertyName: "mobile.multicampaign.demo", gdpr: true, ccpa: true, @@ -59,9 +63,6 @@ In order to instantiate & trigger `Consent Message Web View`, you must call the | `accountId` | Organization's account ID found in the Sourcepoint portal | | `propertyId` | ID for property found in the Sourcepoint portal | | `propertyName` | Name of property found in the Sourcepoint portal | -| `gdpr` | Allows using `gdpr` campaign | -| `ccpa` | Allows using `ccpa` campaign | -| `usnat` | Allows using `usnat` campaign | | `language` | Force a message to be displayed in a certain language. Look `MESSAGE_LANGUAGE` for all available languages | | `gdprPmId` | Id of the privacy manager for `gdpr` campaign | | `ccpaPmId` | Id of the privacy manager for `ccpa` campaign | From a67bee1d1f6b83839fb5e9836409cc8d0c3e057a Mon Sep 17 00:00:00 2001 From: Dmytro Date: Fri, 15 Mar 2024 17:19:10 +0100 Subject: [PATCH 08/10] DIA-3630 Remove bool flags from `CMP.Initialize` --- .../Scripts/facade/CMP.cs | 24 ++++++---- Assets/ExampleApp/Scripts/PrivacySettings.cs | 48 ++++++++----------- 2 files changed, 33 insertions(+), 39 deletions(-) diff --git a/Assets/ConsentManagementProvider/Scripts/facade/CMP.cs b/Assets/ConsentManagementProvider/Scripts/facade/CMP.cs index 9d2624e2..ad5aed23 100644 --- a/Assets/ConsentManagementProvider/Scripts/facade/CMP.cs +++ b/Assets/ConsentManagementProvider/Scripts/facade/CMP.cs @@ -23,10 +23,7 @@ public static void Initialize( List spCampaigns, int accountId, int propertyId, - string propertyName, - bool gdpr, - bool ccpa, - bool usnat, + string propertyName, MESSAGE_LANGUAGE language, string gdprPmId, string ccpaPmId, @@ -40,9 +37,16 @@ public static void Initialize( { return; } - useGDPR = gdpr; - useCCPA = ccpa; - useUSNAT = usnat; + + foreach (SpCampaign sp in spCampaigns) + { + switch (sp.CampaignType) + { + case CAMPAIGN_TYPE.GDPR: useGDPR = true; break; + case CAMPAIGN_TYPE.CCPA: useCCPA = true; break; + case CAMPAIGN_TYPE.USNAT: useUSNAT = true; break; + } + } #if UNITY_ANDROID CreateBroadcastExecutorGO(); //excluding ios14 campaign if any @@ -68,9 +72,9 @@ public static void Initialize( accountId, propertyId, propertyName, - gdpr, - ccpa, - usnat, + useGDPR, + useCCPA, + useUSNAT, language, gdprPmId, ccpaPmId, diff --git a/Assets/ExampleApp/Scripts/PrivacySettings.cs b/Assets/ExampleApp/Scripts/PrivacySettings.cs index 99be1d59..0a6d5eb7 100644 --- a/Assets/ExampleApp/Scripts/PrivacySettings.cs +++ b/Assets/ExampleApp/Scripts/PrivacySettings.cs @@ -9,9 +9,6 @@ public class PrivacySettings : MonoBehaviour, IOnConsentReady public int accountId = 22; public int propertyId = 16893; public string propertyName = "mobile.multicampaign.demo"; - public bool useGDPR = true; - public bool useCCPA = true; - public bool useUSNAT = true; public string gdprPmId = "488393"; public string ccpaPmId = "509688"; public string usnatPmId = "943886"; @@ -52,33 +49,26 @@ private void Awake() ConsentMessenger.AddListener(gameObject); List spCampaigns = new List(); - if (useGDPR) - { - List gdprParams = new List { new TargetingParam("location", "EU") }; - SpCampaign gdpr = new SpCampaign(CAMPAIGN_TYPE.GDPR, gdprParams); - spCampaigns.Add(gdpr); - } - if (useCCPA) - { - List ccpaParams = new List { new TargetingParam("location", "US") }; - SpCampaign ccpa = new SpCampaign(CAMPAIGN_TYPE.CCPA, ccpaParams); - spCampaigns.Add(ccpa); - } - if (useUSNAT) - { - List usnatParams = new List { new TargetingParam("location", "US") }; - SpCampaign usnat = new SpCampaign(CAMPAIGN_TYPE.USNAT, usnatParams); - spCampaigns.Add(usnat); - } + List gdprParams = new List { new TargetingParam("location", "EU") }; + SpCampaign gdpr = new SpCampaign(CAMPAIGN_TYPE.GDPR, gdprParams); + spCampaigns.Add(gdpr); + campaignTypes.Add(CAMPAIGN_TYPE.GDPR); + + List ccpaParams = new List { new TargetingParam("location", "US") }; + SpCampaign ccpa = new SpCampaign(CAMPAIGN_TYPE.CCPA, ccpaParams); + spCampaigns.Add(ccpa); + campaignTypes.Add(CAMPAIGN_TYPE.CCPA); + + List usnatParams = new List { new TargetingParam("location", "US") }; + SpCampaign usnat = new SpCampaign(CAMPAIGN_TYPE.USNAT, usnatParams); + spCampaigns.Add(usnat); + campaignTypes.Add(CAMPAIGN_TYPE.USNAT); CMP.Initialize( spCampaigns: spCampaigns, accountId: accountId, propertyId: propertyId, propertyName: propertyName, - gdpr: useGDPR, - ccpa: useCCPA, - usnat: useUSNAT, language: language, gdprPmId: gdprPmId, ccpaPmId: ccpaPmId, @@ -166,9 +156,9 @@ public void OnClearDataPress() public void OnConsentReady(SpConsents consents) { storedConsentString = consents.gdpr.consents.euconsent ?? "--"; - if(useGDPR) + if(CMP.useGDPR) CmpDebugUtil.Log(consents.gdpr.consents.ToFullString()); - if(useUSNAT) + if(CMP.useUSNAT) CmpDebugUtil.Log(consents.usnat.consents.ToFullString()); updateUI(); } @@ -178,9 +168,9 @@ private void updateUI() if (storedConsentString != null) { loadMessageButton.interactable = false; - gdprPrivacySettingsButton.interactable = useGDPR; - ccpaPrivacySettingsButton.interactable = useCCPA; - usnatPrivacySettingsButton.interactable = useUSNAT; + gdprPrivacySettingsButton.interactable = CMP.useGDPR; + ccpaPrivacySettingsButton.interactable = CMP.useCCPA; + usnatPrivacySettingsButton.interactable = CMP.useUSNAT; customConsentButton.interactable = true; deleteCustomConsentButton.interactable = true; clearDataButton.interactable = true; From f43b37eac966e031a7369ef3aade80a27b6a67c6 Mon Sep 17 00:00:00 2001 From: Dmytro Date: Fri, 22 Mar 2024 13:38:38 +0200 Subject: [PATCH 09/10] DIA-3630 Update `dependencies` to `7.8.1` --- .../Editor/SourcepointDependencies.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/ExternalDependencyManager/Editor/SourcepointDependencies.xml b/Assets/ExternalDependencyManager/Editor/SourcepointDependencies.xml index 156a0e06..02027e00 100644 --- a/Assets/ExternalDependencyManager/Editor/SourcepointDependencies.xml +++ b/Assets/ExternalDependencyManager/Editor/SourcepointDependencies.xml @@ -39,6 +39,6 @@ - + From ef8c47a01593ccf7001d35b44413c66160375237 Mon Sep 17 00:00:00 2001 From: Dmytro Date: Fri, 22 Mar 2024 14:48:50 +0200 Subject: [PATCH 10/10] DIA-3630 Update `README.md` --- README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 13044150..b75407d7 100644 --- a/README.md +++ b/README.md @@ -366,4 +366,18 @@ It's important to notice, this methods are intended to be used for **custom** ve # Build for iOS -Since Unity Editor exports the pre-built project to Xcode on iOS build, there are several necessary steps to perform so you can compile your solution. They are implemented inside the `CMPPostProcessBuild` [PostProcessBuild] script. Supplement or modify it if it is needed. +Since Unity Editor exports the pre-built project to Xcode on iOS build, there are several necessary steps to perform so you can compile your solution. They are implemented inside the `CMPPostProcessBuild` [PostProcessBuild] script. Supplement or modify it if it is needed. + +You also need to check lines `33`, `55` and `90` of the `CMPPostProcessBuild` script, the paths may differ. Check that the path of the file `SwiftBridge.swift` in the Unity project matches that specified in the `33` line and the `55` line in the exported Xcode project. You also need to check the path of the file `UnityPlugin-Bridging-Header.h` in the project exported to xcode with path on line `90`. + +## Troubleshooting +### `ConsentViewController-Swift.h` file not found (IOS) +Every time you update the Unity SDK from an older to a newer version, you are likely to encounter the absence of the newer version of the native iOS SDK in your build machine's cocoapods cache. +The fix is: +Try to update cocoapods to the latest version (1.15.2 at the moment) on your build machine and execute the commands consequently: +1) pod update +2) pod install + +In the terminal where the "Podfile" is situated (usually, it is situated in the folder where Unity exports the Xcode project). +It will fetch the native ConsentViewController version specified in Podfile (X.Y.Z) in your build machine cache. +It should be performed once, after this the build machine will have an X.Y.Z version of SDK in cocoapod's cache and consequent builds will go smoothly.