Skip to content

Commit bb60908

Browse files
authored
Merge pull request #3 from contentpass/CP-2491-Integrate-demo-app-with-react-native-Sourcepoint-SDK
feat: integrate demo app with react-native Sourcepoint SDK
2 parents 39e379c + 347e661 commit bb60908

File tree

19 files changed

+364
-31
lines changed

19 files changed

+364
-31
lines changed

.eslintignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
node_modules/
22
lib/
3+
ios/
4+
android/
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
diff --git a/android/src/main/java/com/sourcepoint/reactnativecmp/RNSourcepointCmpModule.kt b/android/src/main/java/com/sourcepoint/reactnativecmp/RNSourcepointCmpModule.kt
2+
index deb04fb18dbd8adffcb225801ad35b3154a3c7ad..4d372d921cbae6163179435feb9c821e3c37134b 100644
3+
--- a/android/src/main/java/com/sourcepoint/reactnativecmp/RNSourcepointCmpModule.kt
4+
+++ b/android/src/main/java/com/sourcepoint/reactnativecmp/RNSourcepointCmpModule.kt
5+
@@ -119,6 +119,7 @@ class RNSourcepointCmpModule internal constructor(context: ReactApplicationConte
6+
override fun onAction(view: View, consentAction: ConsentAction): ConsentAction {
7+
sendEvent(SDKEvent.onAction, createMap().apply {
8+
putString("actionType", RNSourcepointActionType.from(consentAction.actionType).name)
9+
+ putString("customActionId", consentAction.customActionId ?: "")
10+
})
11+
return consentAction
12+
}
13+
diff --git a/ios/RNSourcepointCmp.swift b/ios/RNSourcepointCmp.swift
14+
index 556b56618c847ad8aeaf9cdc680813cc26b732a9..ba7d707232d72fe5038ec05fb6fdb8e27216e4ee 100644
15+
--- a/ios/RNSourcepointCmp.swift
16+
+++ b/ios/RNSourcepointCmp.swift
17+
@@ -69,7 +69,10 @@ extension RNSourcepointCmp: SPDelegate {
18+
func onAction(_ action: SPAction, from controller: UIViewController) {
19+
RNSourcepointCmp.shared?.sendEvent(
20+
withName: "onAction",
21+
- body: ["actionType": RNSourcepointActionType(from: action.type).rawValue]
22+
+ body: [
23+
+ "actionType": RNSourcepointActionType(from: action.type).rawValue,
24+
+ "customActionId": action.customActionId ?? "",
25+
+ ]
26+
)
27+
}
28+
29+
diff --git a/lib/typescript/src/index.d.ts b/lib/typescript/src/index.d.ts
30+
index 1602516717becd5ec0a8e5036ad2d821110af96f..67bb9e5153b7489c5ead4dcd056b502b71bc2a7d 100644
31+
--- a/lib/typescript/src/index.d.ts
32+
+++ b/lib/typescript/src/index.d.ts
33+
@@ -12,6 +12,7 @@ export declare class SPConsentManager implements Spec {
34+
loadUSNatPrivacyManager(pmId: string): void;
35+
onAction(callback: (body: {
36+
actionType: SPActionType;
37+
+ customActionId: string;
38+
}) => void): void;
39+
onSPUIReady(callback: () => void): void;
40+
onSPUIFinished(callback: () => void): void;
41+
diff --git a/lib/typescript/src/types.d.ts b/lib/typescript/src/types.d.ts
42+
index a15f7a06c3e0635168987a44a33009ff42bbd31c..a035a72af14f32adf0ff88f959eb8c517ffaea47 100644
43+
--- a/lib/typescript/src/types.d.ts
44+
+++ b/lib/typescript/src/types.d.ts
45+
@@ -86,6 +86,7 @@ export interface Spec extends TurboModule {
46+
loadUSNatPrivacyManager(pmId: string): void;
47+
onAction(callback: (body: {
48+
actionType: SPActionType;
49+
+ customActionId: string;
50+
}) => void): void;
51+
onSPUIReady(callback: () => void): void;
52+
onSPUIFinished(callback: () => void): void;
53+
diff --git a/src/index.ts b/src/index.ts
54+
index b3e76b15572c56f1a4e54068b90243d6dd028e18..a03d87fea4a93edb6bf904c99d32b029b840bade 100644
55+
--- a/src/index.ts
56+
+++ b/src/index.ts
57+
@@ -67,7 +67,7 @@ export class SPConsentManager implements Spec {
58+
RNSourcepointCmp.loadUSNatPrivacyManager(pmId);
59+
}
60+
61+
- onAction(callback: (body: { actionType: SPActionType }) => void): void {
62+
+ onAction(callback: (body: { actionType: SPActionType, customActionId: string }) => void): void {
63+
this.emitter.removeAllListeners('onAction');
64+
this.emitter.addListener('onAction', callback);
65+
}
66+
diff --git a/src/types.ts b/src/types.ts
67+
index 26ac3d8162c0534af98e2a20d237856195fe5a10..4257aff5ed128988c7d3fba60545672966162b20 100644
68+
--- a/src/types.ts
69+
+++ b/src/types.ts
70+
@@ -113,7 +113,7 @@ export interface Spec extends TurboModule {
71+
loadGDPRPrivacyManager(pmId: string): void;
72+
loadUSNatPrivacyManager(pmId: string): void;
73+
74+
- onAction(callback: (body: { actionType: SPActionType }) => void): void;
75+
+ onAction(callback: (body: { actionType: SPActionType, customActionId: string }) => void): void;
76+
onSPUIReady(callback: () => void): void;
77+
onSPUIFinished(callback: () => void): void;
78+
onFinished(callback: () => void): void;

example/android/gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
3232
# your application. You should enable this flag either if you want
3333
# to write custom TurboModules/Fabric components OR use libraries that
3434
# are providing them.
35-
newArchEnabled=true
35+
newArchEnabled=false
3636

3737
# Use this property to enable or disable the Hermes JS engine.
3838
# If set to false, you will be using JSC instead.

example/ios/ContentpassExample/PrivacyInfo.xcprivacy

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,18 @@
66
<array>
77
<dict>
88
<key>NSPrivacyAccessedAPIType</key>
9-
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
9+
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
1010
<key>NSPrivacyAccessedAPITypeReasons</key>
1111
<array>
12-
<string>C617.1</string>
12+
<string>CA92.1</string>
1313
</array>
1414
</dict>
1515
<dict>
1616
<key>NSPrivacyAccessedAPIType</key>
17-
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
17+
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
1818
<key>NSPrivacyAccessedAPITypeReasons</key>
1919
<array>
20-
<string>CA92.1</string>
20+
<string>C617.1</string>
2121
</array>
2222
</dict>
2323
<dict>

example/ios/Podfile.lock

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ PODS:
66
- AppAuth/ExternalUserAgent (1.7.5):
77
- AppAuth/Core
88
- boost (1.84.0)
9+
- ConsentViewController (7.6.7):
10+
- Down (~> 0.11.0)
911
- DoubleConversion (1.1.6)
1012
- FBLazyVector (0.76.2)
1113
- fmt (9.1.0)
@@ -1542,6 +1544,28 @@ PODS:
15421544
- React-perflogger (= 0.76.2)
15431545
- React-utils (= 0.76.2)
15441546
- SocketRocket (0.7.1)
1547+
- sourcepoint-react-native-cmp (0.3.0):
1548+
- ConsentViewController (= 7.6.7)
1549+
- DoubleConversion
1550+
- glog
1551+
- hermes-engine
1552+
- RCT-Folly (= 2024.01.01.00)
1553+
- RCTRequired
1554+
- RCTTypeSafety
1555+
- React-Core
1556+
- React-debug
1557+
- React-Fabric
1558+
- React-featureflags
1559+
- React-graphics
1560+
- React-ImageManager
1561+
- React-NativeModulesApple
1562+
- React-RCTFabric
1563+
- React-rendererdebug
1564+
- React-utils
1565+
- ReactCodegen
1566+
- ReactCommon/turbomodule/bridging
1567+
- ReactCommon/turbomodule/core
1568+
- Yoga
15451569
- Yoga (0.0.0)
15461570

15471571
DEPENDENCIES:
@@ -1612,11 +1636,13 @@ DEPENDENCIES:
16121636
- React-utils (from `../node_modules/react-native/ReactCommon/react/utils`)
16131637
- ReactCodegen (from `build/generated/ios`)
16141638
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
1639+
- "sourcepoint-react-native-cmp (from `../node_modules/@sourcepoint/react-native-cmp`)"
16151640
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
16161641

16171642
SPEC REPOS:
16181643
trunk:
16191644
- AppAuth
1645+
- ConsentViewController
16201646
- SocketRocket
16211647

16221648
EXTERNAL SOURCES:
@@ -1751,12 +1777,15 @@ EXTERNAL SOURCES:
17511777
:path: build/generated/ios
17521778
ReactCommon:
17531779
:path: "../node_modules/react-native/ReactCommon"
1780+
sourcepoint-react-native-cmp:
1781+
:path: "../node_modules/@sourcepoint/react-native-cmp"
17541782
Yoga:
17551783
:path: "../node_modules/react-native/ReactCommon/yoga"
17561784

17571785
SPEC CHECKSUMS:
17581786
AppAuth: 501c04eda8a8d11f179dbe8637b7a91bb7e5d2fa
17591787
boost: 1dca942403ed9342f98334bf4c3621f011aa7946
1788+
ConsentViewController: 243f7bfcde4b6ec71a5033486465b7c17448493c
17601789
DoubleConversion: f16ae600a246532c4020132d54af21d0ddb2a385
17611790
FBLazyVector: bc70dcb22ad30ce734a7cce7210791dc737e230f
17621791
fmt: 10c6e61f4be25dc963c36bd73fc7b1705fe975be
@@ -1822,6 +1851,7 @@ SPEC CHECKSUMS:
18221851
ReactCodegen: 93b271af49774429f34d7fd561197020d86436e2
18231852
ReactCommon: 208cb02e3c0bb8a727b3e1a1782202bcfa5d9631
18241853
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
1854+
sourcepoint-react-native-cmp: 895d48d036184268872955c4df25bb3bd44c2266
18251855
Yoga: 96872ee462cfc43866ad013c8160d4ff6b85709b
18261856

18271857
PODFILE CHECKSUM: c50a131c6dd5a8e1657bf6b76ff12413d914b88e

example/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"build:ios": "react-native build-ios --scheme ContentpassExample --mode Debug --extra-params \"-sdk iphonesimulator CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ GCC_OPTIMIZATION_LEVEL=0 GCC_PRECOMPILE_PREFIX_HEADER=YES ASSETCATALOG_COMPILER_OPTIMIZATION=time DEBUG_INFORMATION_FORMAT=dwarf COMPILER_INDEX_STORE_ENABLE=NO\""
1111
},
1212
"dependencies": {
13+
"@sourcepoint/react-native-cmp": "^0.3.0",
1314
"react": "18.3.1",
1415
"react-native": "0.76.2",
1516
"react-native-app-auth": "^8.0.0",

example/src/ContentpassUsage.tsx

Lines changed: 81 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,99 @@
11
import { useContentpassSdk } from './ContentpassContext';
2-
import { Button, Text } from 'react-native';
3-
import { useState } from 'react';
2+
import { Button, ScrollView, StyleSheet, Text, View } from 'react-native';
3+
import { useCallback, useEffect, useRef, useState } from 'react';
44
import type { AuthenticateResult } from 'react-native-contentpass';
5+
import {
6+
SPConsentManager,
7+
type SPUserData,
8+
} from '@sourcepoint/react-native-cmp';
9+
10+
const styles = StyleSheet.create({
11+
sourcepointDataContainer: {
12+
padding: 10,
13+
height: 400,
14+
flexGrow: 0,
15+
},
16+
logsView: {
17+
marginTop: 10,
18+
},
19+
});
20+
21+
const sourcePointConfig = {
22+
accountId: 375,
23+
propertyId: 37858,
24+
propertyName: 'mobile.cmpsourcepoint.demo',
25+
};
26+
27+
const setupSourcepoint = (hasValidSubscription: boolean) => {
28+
const { accountId, propertyName, propertyId } = sourcePointConfig;
29+
const spConsentManager = new SPConsentManager();
30+
31+
spConsentManager.build(accountId, propertyId, propertyName, {
32+
gdpr: {
33+
targetingParams: {
34+
acps: hasValidSubscription ? 'true' : 'false',
35+
},
36+
},
37+
});
38+
39+
return spConsentManager;
40+
};
541

642
export default function ContentpassUsage() {
743
const [authResult, setAuthResult] = useState<
844
AuthenticateResult | undefined
945
>();
1046
const contentpassSdk = useContentpassSdk();
47+
const spConsentManager = useRef<SPConsentManager | null>();
48+
const [sourcepointUserData, setSourcepointUserData] = useState<
49+
SPUserData | undefined
50+
>();
1151

12-
const authenticate = async () => {
52+
const authenticate = useCallback(async () => {
53+
spConsentManager.current?.dispose();
1354
const result = await contentpassSdk.authenticate();
1455
setAuthResult(result);
56+
}, [contentpassSdk]);
57+
58+
useEffect(() => {
59+
spConsentManager.current = setupSourcepoint(
60+
authResult?.hasValidSubscription ?? false
61+
);
62+
63+
spConsentManager.current?.onFinished(() => {
64+
spConsentManager.current?.getUserData().then(setSourcepointUserData);
65+
});
66+
67+
spConsentManager.current?.onAction((action) => {
68+
if (action.customActionId === "cp('login')") {
69+
authenticate();
70+
}
71+
});
72+
73+
spConsentManager.current?.loadMessage();
74+
75+
return () => {
76+
spConsentManager.current?.dispose();
77+
};
78+
}, [authResult, authenticate]);
79+
80+
const clearSourcepointData = () => {
81+
spConsentManager.current?.clearLocalData();
82+
setSourcepointUserData(undefined);
83+
spConsentManager.current?.loadMessage();
1584
};
1685

1786
return (
1887
<>
19-
<Button title={'Authenticate'} onPress={authenticate} />
20-
<Text>Result: {JSON.stringify(authResult)}</Text>
88+
<Button title={'Clear sourcepoint data'} onPress={clearSourcepointData} />
89+
<View style={styles.logsView}>
90+
<Text>Authenticate result:</Text>
91+
<Text>{JSON.stringify(authResult, null, 2)}</Text>
92+
<Text>Sourcepoint user data:</Text>
93+
<ScrollView style={styles.sourcepointDataContainer}>
94+
<Text>{JSON.stringify(sourcepointUserData, null, 2)}</Text>
95+
</ScrollView>
96+
</View>
2197
</>
2298
);
2399
}

expoExample/android/gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
3535
# your application. You should enable this flag either if you want
3636
# to write custom TurboModules/Fabric components OR use libraries that
3737
# are providing them.
38-
newArchEnabled=true
38+
newArchEnabled=false
3939

4040
# Use this property to enable or disable the Hermes JS engine.
4141
# If set to false, you will be using JSC instead.

expoExample/app.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"orientation": "portrait",
77
"icon": "./assets/icon.png",
88
"userInterfaceStyle": "light",
9-
"newArchEnabled": true,
9+
"newArchEnabled": false,
1010
"splash": {
1111
"image": "./assets/splash-icon.png",
1212
"resizeMode": "contain",

expoExample/ios/ContentpassExpoExample.xcodeproj/project.pbxproj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,12 @@
274274
inputPaths = (
275275
"${PODS_ROOT}/Target Support Files/Pods-ContentpassExpoExample/Pods-ContentpassExpoExample-resources.sh",
276276
"${PODS_CONFIGURATION_BUILD_DIR}/AppAuth/AppAuthCore_Privacy.bundle",
277+
"${PODS_ROOT}/ConsentViewController/ConsentViewController/Assets/images/Barcode.png",
278+
"${PODS_ROOT}/ConsentViewController/ConsentViewController/Assets/images/SP_Icon.png",
279+
"${PODS_ROOT}/ConsentViewController/ConsentViewController/Assets/javascript/jest.config.json",
280+
"${PODS_ROOT}/ConsentViewController/ConsentViewController/Assets/javascript/SPJSReceiver.js",
281+
"${PODS_ROOT}/ConsentViewController/ConsentViewController/Assets/javascript/SPJSReceiver.spec.js",
282+
"${PODS_CONFIGURATION_BUILD_DIR}/ConsentViewController/ConsentViewController.bundle",
277283
"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/EXConstants.bundle",
278284
"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/ExpoConstants_privacy.bundle",
279285
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoFileSystem/ExpoFileSystem_privacy.bundle",
@@ -286,6 +292,12 @@
286292
name = "[CP] Copy Pods Resources";
287293
outputPaths = (
288294
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AppAuthCore_Privacy.bundle",
295+
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Barcode.png",
296+
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SP_Icon.png",
297+
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/jest.config.json",
298+
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SPJSReceiver.js",
299+
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SPJSReceiver.spec.js",
300+
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ConsentViewController.bundle",
289301
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXConstants.bundle",
290302
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoConstants_privacy.bundle",
291303
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoFileSystem_privacy.bundle",

0 commit comments

Comments
 (0)