Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ Refer to the table below regarding the different campaigns that can be implement
| `gdpr: {}` | Used if your property runs a GDPR TCF or GDPR Standard campaign |
| `usnat: {}` | Used if your property runs a U.S. Multi-State Privacy campaign |
| `preferences: {}` | Used if your property runs a Preferences campaign |
| `globalCMP: {}` | Used if your property runs a Global CMP campaign |

### Set up callbacks in instance of `SPConsentManager`

Expand Down
2 changes: 1 addition & 1 deletion ReactNativeCmp.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Pod::Spec.new do |s|
s.platforms = { :ios => min_ios_version_supported }
s.source = { :git => "https://github.com/SourcePointUSA/react-native-sourcepoint-cmp.git", :tag => "#{s.version}" }

s.dependency "ConsentViewController", "7.9.1"
s.dependency "ConsentViewController", "7.10.0"
s.source_files = "ios/**/*.{h,m,mm,cpp,swift}"
s.private_header_files = "ios/**/*.h"

Expand Down
4 changes: 2 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ buildscript {
}

dependencies {
classpath "com.android.tools.build:gradle:8.7.2"
classpath "com.android.tools.build:gradle:8.7.3"
// noinspection DifferentKotlinGradleVersion
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
}
Expand Down Expand Up @@ -77,7 +77,7 @@ dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3"
implementation "org.jetbrains.kotlinx:kotlinx-datetime:0.6.1"

implementation "com.sourcepoint.cmplibrary:cmplibrary:7.14.1-beta2"
implementation "com.sourcepoint.cmplibrary:cmplibrary:7.15.0"
}

react {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ package com.sourcepoint.reactnativecmp

import com.facebook.react.bridge.ReadableMap
import com.sourcepoint.cmplibrary.model.CampaignsEnv
import com.sourcepoint.cmplibrary.model.CampaignsEnv.*
import com.sourcepoint.cmplibrary.model.exposed.ActionType
import com.sourcepoint.cmplibrary.model.exposed.ActionType.*
import com.sourcepoint.cmplibrary.model.exposed.TargetingParam

fun campaignsEnvFrom(rawValue: String?): CampaignsEnv? =
when (rawValue) {
"Public" -> CampaignsEnv.PUBLIC
"Stage" -> CampaignsEnv.STAGE
"Public" -> PUBLIC
"Stage" -> STAGE
else -> { null }
}

Expand All @@ -18,13 +19,16 @@ data class SPCampaign(
val supportLegacyUSPString: Boolean,
val groupPmId: String? = null,
) {
val targetingParams = rawTargetingParam?.toHashMap()?.map { TargetingParam(it.key, it.value.toString()) } ?: emptyList()
val targetingParams = rawTargetingParam?.toHashMap()?.map {
TargetingParam(it.key, it.value.toString())
} ?: emptyList()
}

data class SPCampaigns(
val gdpr: SPCampaign?,
val usnat: SPCampaign?,
val preferences: SPCampaign?,
val globalcmp: SPCampaign?,
val environment: CampaignsEnv?
)

Expand Down Expand Up @@ -55,5 +59,6 @@ fun ReadableMap.SPCampaigns() = SPCampaigns(
gdpr = this.getMap("gdpr")?.SPCampaign(),
usnat = this.getMap("usnat")?.SPCampaign(),
preferences = this.getMap("preferences")?.SPCampaign(),
globalcmp = this.getMap("globalcmp")?.SPCampaign(),
environment = campaignsEnvFrom(rawValue = this.getString("environment"))
)
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import com.sourcepoint.cmplibrary.NativeMessageController
import com.sourcepoint.cmplibrary.SpClient
import com.sourcepoint.cmplibrary.SpConsentLib
import com.sourcepoint.cmplibrary.core.nativemessage.MessageStructure
import com.sourcepoint.cmplibrary.creation.ConfigOption
import com.sourcepoint.cmplibrary.creation.ConfigOption.SUPPORT_LEGACY_USPSTRING
import com.sourcepoint.cmplibrary.creation.SpConfigDataBuilder
import com.sourcepoint.cmplibrary.creation.makeConsentLib
import com.sourcepoint.cmplibrary.data.network.util.CampaignType
import com.sourcepoint.cmplibrary.data.network.util.CampaignType.*
import com.sourcepoint.cmplibrary.model.ConsentAction
import com.sourcepoint.cmplibrary.model.exposed.SPConsents
import com.sourcepoint.cmplibrary.util.clearAllData
Expand Down Expand Up @@ -47,18 +47,21 @@ class ReactNativeCmpModule(reactContext: ReactApplicationContext) : NativeReactN
addPropertyId(propertyId.toInt())
addMessageTimeout(30000)
convertedCampaigns.gdpr?.let {
addCampaign(campaignType = CampaignType.GDPR, params = it.targetingParams, groupPmId = it.groupPmId)
addCampaign(campaignType = GDPR, params = it.targetingParams, groupPmId = it.groupPmId)
}
convertedCampaigns.usnat?.let {
addCampaign(
campaignType = CampaignType.USNAT,
campaignType = USNAT,
params = it.targetingParams,
groupPmId = it.groupPmId,
configParams = if(it.supportLegacyUSPString) setOf(ConfigOption.SUPPORT_LEGACY_USPSTRING) else emptySet()
configParams = if(it.supportLegacyUSPString) setOf(SUPPORT_LEGACY_USPSTRING) else emptySet()
)
}
convertedCampaigns.preferences?.let {
addCampaign(campaignType = CampaignType.PREFERENCES, params = it.targetingParams, groupPmId = it.groupPmId)
addCampaign(campaignType = PREFERENCES, params = it.targetingParams, groupPmId = it.groupPmId)
}
convertedCampaigns.globalcmp?.let {
addCampaign(campaignType = GLOBALCMP, params = it.targetingParams, groupPmId = it.groupPmId)
}
}.build()

Expand Down Expand Up @@ -95,12 +98,16 @@ class ReactNativeCmpModule(reactContext: ReactApplicationContext) : NativeReactN

@ReactMethod
override fun loadGDPRPrivacyManager(pmId: String) {
runOnMainThread { spConsentLib?.loadPrivacyManager(pmId, CampaignType.GDPR) }
runOnMainThread { spConsentLib?.loadPrivacyManager(pmId, GDPR) }
}

@ReactMethod
override fun loadUSNatPrivacyManager(pmId: String) {
runOnMainThread { spConsentLib?.loadPrivacyManager(pmId, CampaignType.USNAT) }
runOnMainThread { spConsentLib?.loadPrivacyManager(pmId, USNAT) }
}

override fun loadGlobalCmpPrivacyManager(pmId: String) {
runOnMainThread { spConsentLib?.loadPrivacyManager(pmId, GLOBALCMP) }
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.sourcepoint.reactnativecmp.consents

import com.facebook.react.bridge.Arguments.createMap
import com.facebook.react.bridge.ReadableMap
import com.sourcepoint.cmplibrary.model.exposed.Consentable

data class RNSPConsentable(override val id: String, override val consented: Boolean): Consentable, RNMappable {
constructor(spConsentable: Consentable): this(
id = spConsentable.id,
consented = spConsentable.consented
)

override fun toRN(): ReadableMap = createMap().apply {
putString("id", id)
putBoolean("consented", consented)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.sourcepoint.reactnativecmp.consents

import com.facebook.react.bridge.Arguments.createArray
import com.facebook.react.bridge.Arguments.createMap
import com.facebook.react.bridge.ReadableMap
import com.sourcepoint.cmplibrary.model.exposed.GlobalCmpConsent

data class RNSPGlobalCMPConsent(
val uuid: String?,
val applies: Boolean,
val createdDate: String?,
val expirationDate: String?,
val vendors: List<RNSPConsentable>,
val categories: List<RNSPConsentable>
): RNMappable {
constructor(globalCMP: GlobalCmpConsent) : this(
uuid = globalCMP.uuid,
applies = globalCMP.applies,
createdDate = globalCMP.dateCreated,
expirationDate = null,
vendors = globalCMP.vendors?.map { RNSPConsentable(it) } ?: emptyList(),
categories = globalCMP.categories?.map { RNSPConsentable(it) } ?: emptyList()
)

override fun toRN(): ReadableMap = createMap().apply {
putString("uuid", uuid)
putBoolean("applies", applies)
putString("createdDate", createdDate)
putString("expirationDate", expirationDate)
putArray("vendors", createArray().apply { vendors.forEach { pushMap(it.toRN()) } })
putArray("categories", createArray().apply { categories.forEach { pushMap(it.toRN()) } })
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,10 @@ import com.facebook.react.bridge.Arguments.createArray
import com.facebook.react.bridge.Arguments.createMap
import com.facebook.react.bridge.ReadableMap
import com.sourcepoint.cmplibrary.data.network.model.optimized.USNatConsentData.ConsentString
import com.sourcepoint.cmplibrary.model.exposed.Consentable
import com.sourcepoint.cmplibrary.model.exposed.UsNatConsent
import com.sourcepoint.cmplibrary.model.exposed.UsNatStatuses
import com.sourcepoint.reactnativecmp.arguments.putAny

typealias SPConsentable = Consentable

data class RNSPUSNatConsent(
val uuid: String?,
val applies: Boolean,
Expand All @@ -19,8 +16,8 @@ data class RNSPUSNatConsent(
val consentSections: List<ConsentSection>,
val statuses: Statuses,
val gppData: Map<String, Any?>,
val vendors: List<Consentable>,
val categories: List<Consentable>
val vendors: List<RNSPConsentable>,
val categories: List<RNSPConsentable>
): RNMappable {
data class ConsentSection(val id: Int?, val name: String?, val consentString: String?) {
constructor(section: ConsentString): this(
Expand Down Expand Up @@ -66,18 +63,6 @@ data class RNSPUSNatConsent(
}
}

data class Consentable(override val id: String, override val consented: Boolean): SPConsentable, RNMappable {
constructor(spConsentable: SPConsentable): this(
id = spConsentable.id,
consented = spConsentable.consented
)

override fun toRN(): ReadableMap = createMap().apply {
putString("id", id)
putBoolean("consented", consented)
}
}

constructor(usnat: UsNatConsent) : this(
uuid = usnat.uuid,
applies = usnat.applies,
Expand All @@ -86,8 +71,8 @@ data class RNSPUSNatConsent(
consentSections = usnat.consentStrings?.map { ConsentSection(section = it) } ?: emptyList(),
statuses = Statuses(status = usnat.statuses),
gppData = usnat.gppData,
vendors = usnat.vendors?.map { Consentable(it) } ?: emptyList(),
categories = usnat.categories?.map { Consentable(it) } ?: emptyList(),
vendors = usnat.vendors?.map { RNSPConsentable(it) } ?: emptyList(),
categories = usnat.categories?.map { RNSPConsentable(it) } ?: emptyList(),
)

override fun toRN(): ReadableMap = createMap().apply {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.sourcepoint.reactnativecmp.consents

import com.facebook.react.bridge.Arguments.createArray
import com.facebook.react.bridge.Arguments.createMap
import com.facebook.react.bridge.ReadableMap
import com.sourcepoint.cmplibrary.model.exposed.PreferencesConsent
import com.sourcepoint.cmplibrary.model.exposed.SPConsents

interface RNMappable {
Expand All @@ -13,17 +11,20 @@ interface RNMappable {
data class RNSPUserData(
val gdpr: RNSPGDPRConsent?,
val usnat: RNSPUSNatConsent?,
val preferences: RNSPPreferencesConsent?
val preferences: RNSPPreferencesConsent?,
val globalCMP: RNSPGlobalCMPConsent?
): RNMappable {
constructor(spData: SPConsents): this(
gdpr = spData.gdpr?.let { RNSPGDPRConsent(gdpr = it.consent)},
usnat = spData.usNat?.let { RNSPUSNatConsent(usnat = it.consent)},
preferences = spData.preferences?.let { RNSPPreferencesConsent(preferences = it.consent) }
preferences = spData.preferences?.let { RNSPPreferencesConsent(preferences = it.consent) },
globalCMP = spData.globalcmp?.let { RNSPGlobalCMPConsent(globalCMP = it.consent) }
)

override fun toRN(): ReadableMap = createMap().apply {
gdpr?.let { putMap("gdpr", it.toRN()) }
usnat?.let { putMap("usnat", it.toRN()) }
preferences?.let { putMap("preferences", it.toRN()) }
globalCMP?.let { putMap("globalcmp", it.toRN()) }
}
}
14 changes: 7 additions & 7 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
PODS:
- boost (1.84.0)
- ConsentViewController (7.9.1):
- ConsentViewController (7.10.0):
- Down (~> 0.11.0)
- SPMobileCore (= 0.1.7)
- SPMobileCore (= 0.1.9)
- DoubleConversion (1.1.6)
- fast_float (6.1.4)
- FBLazyVector (0.79.2)
Expand Down Expand Up @@ -1660,7 +1660,7 @@ PODS:
- React-perflogger (= 0.79.2)
- React-utils (= 0.79.2)
- ReactNativeCmp (1.0.0):
- ConsentViewController (= 7.9.1)
- ConsentViewController (= 7.10.0)
- DoubleConversion
- glog
- hermes-engine
Expand All @@ -1685,7 +1685,7 @@ PODS:
- ReactCommon/turbomodule/core
- Yoga
- SocketRocket (0.7.1)
- SPMobileCore (0.1.7)
- SPMobileCore (0.1.9)
- Yoga (0.0.0)

DEPENDENCIES:
Expand Down Expand Up @@ -1919,7 +1919,7 @@ EXTERNAL SOURCES:

SPEC CHECKSUMS:
boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90
ConsentViewController: cdd57de154538b2240285cdb5480d3e2fe067fa0
ConsentViewController: 079fad8b149491cfb52ec8bd7cf47c67eabb2b47
DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb
fast_float: 06eeec4fe712a76acc9376682e4808b05ce978b6
FBLazyVector: 84b955f7b4da8b895faf5946f73748267347c975
Expand Down Expand Up @@ -1989,9 +1989,9 @@ SPEC CHECKSUMS:
ReactAppDependencyProvider: 04d5eb15eb46be6720e17a4a7fa92940a776e584
ReactCodegen: c63eda03ba1d94353fb97b031fc84f75a0d125ba
ReactCommon: 76d2dc87136d0a667678668b86f0fca0c16fdeb0
ReactNativeCmp: 176df14602bf3363e3fe2e1c4bef16ab8ad91a6f
ReactNativeCmp: dd8f9f3e203c312712d937263fdc16e7bd1ba3d7
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
SPMobileCore: 880a2689597578811af343a9626311d34b462a50
SPMobileCore: c3bfa7dacf26f6101900afa096a9b945a89f726a
Yoga: c758bfb934100bb4bf9cbaccb52557cee35e8bdf

PODFILE CHECKSUM: decdc7519d77aa5eae65b167fa59bcfce25e15d2
Expand Down
16 changes: 14 additions & 2 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@
propertyName: 'mobile.multicampaign.demo',
gdprPMId: '488393',
usnatPMId: '988851',
globalCmpPMId: '1323762',
campaigns: {
gdpr: {},
usnat: { supportLegacyUSPString: true },
preferences: {},
globalcmp: {},
environment: SPCampaignEnvironment.Public,
} as SPCampaigns,
...launchArgs?.config,
Expand Down Expand Up @@ -108,6 +110,11 @@
consentManager.current?.loadUSNatPrivacyManager(config.usnatPMId);
}, []);

const onGlobalCMPPress = useCallback(() => {
setSDKStatus(SDKStatus.Networking);
consentManager.current?.loadGlobalCmpPrivacyManager(config.globalCmpPMId);
}, []);

const onClearDataPress = useCallback(() => {
consentManager.current?.clearLocalData();
consentManager.current?.build(
Expand Down Expand Up @@ -146,12 +153,17 @@
<Button
title="Load GDPR PM"
onPress={onGDPRPMPress}
disabled={disable}
disabled={disable || config.campaigns.gdpr == undefined}

Check warning on line 156 in example/src/App.tsx

View workflow job for this annotation

GitHub Actions / lint

Expected '===' and instead saw '=='
/>
<Button
title="Load USNAT PM"
onPress={onUSNATPMPress}
disabled={disable}
disabled={disable || config.campaigns.usnat == undefined}

Check warning on line 161 in example/src/App.tsx

View workflow job for this annotation

GitHub Actions / lint

Expected '===' and instead saw '=='
/>
<Button
title="Load GlobalCMP PM"
onPress={onGlobalCMPPress}
disabled={disable || config.campaigns.globalcmp == undefined}

Check warning on line 166 in example/src/App.tsx

View workflow job for this annotation

GitHub Actions / lint

Expected '===' and instead saw '=='
/>
<Button title="Clear All" onPress={onClearDataPress} />
<Text testID="sdkStatus" style={styles.status}>
Expand Down
13 changes: 13 additions & 0 deletions ios/RNSPUserData/RNSPConsentable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import ConsentViewController

struct RNSPConsentable: Encodable {
let id: String
let consented: Bool
}

extension RNSPConsentable {
init(from consentable: SPConsentable) {
id = consentable.id
consented = consentable.consented
}
}
Loading
Loading