diff --git a/CHANGELOG.md b/CHANGELOG.md index 2170340..1e2c97e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,24 @@ [Release Notes](https://docs.usercentrics.com/cmp_in_app_sdk/latest/about/history/) +### 2.29.1 – Aug 5, 2026 +## Features +* **[Unity]** Added `isExempt` to the Unity `ServiceConsent` model, propagating the statistical exception flag to the Unity bridge + +### 2.29.0 – Aug 5, 2026 +## Features +* **[Mediation]** Added Amazon Consent Signal (ACS) mediation support for Android and iOS, including Adjust adapter integration +* **[PUR Compliance]** Added statistical exception disclosure and toggle UI to the first and second layer, and excluded statistical exception services from Reject All/Deny All, supporting the UK DUAA statistical-exception requirement +* **[Unity]** Automated the Unity-flavored SPM release pipeline, publishing `usercentrics-spm-ui`/`usercentrics-spm-sdk` package tags for Unity releases + +## Fixes +* **[Android]** Fixed consent banner rendering behind system bars on edge-to-edge displays +* **[Android]** Fixed `ExternalLinkSpan.onClick` crash on invalid/empty link URLs +* **[iOS]** Fixed app hang caused by synchronous HTML parsing in first-layer banner/content text +* **[Android/iOS]** Removed residual `assert(false)` calls in Additional Consent Mode and CCPA save paths that could crash debug builds +* **[TV]** Fixed `DPAD_DOWN` navigation escaping the second-layer detail list boundary + +## Chores +* **[Unity]** Stripped debug symbols from iOS core release binaries, reducing device binary size by ~31% with no functional change + ### 2.28.2 – Jul 22, 2026 ## Fixes * **[iOS]** Rebuilt `UsercentricsUI.xcframework` with the Xcode 26 / Swift 6.3.3 toolchain, fixing build failures on Xcode 26.6 for apps consuming 2.27.1/2.28.0 (including via the React Native bridge) diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..280a52d --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,95 @@ +# CLAUDE.md + +Guidance for Claude Code when working in this repo. This file is read automatically — keep it accurate as the release process evolves. + +## Repo purpose + +`@usercentrics/react-native-sdk` — React Native bridge/wrapper around the native Usercentrics iOS (`UsercentricsUI`/`Usercentrics` CocoaPods) and Android (`com.usercentrics.sdk:usercentrics-ui`) SDKs. The `sample/` directory is a full RN sample app used to build and test the native bridges (Xcode workspace under `sample/ios`, Gradle project under `sample/android`). + +## Release process ("faz a release X.Y.Z") + +When asked to prepare/cut a release, treat it as a pure **version bump** — the underlying native SDK versions (iOS `Usercentrics`/`UsercentricsUI`, Android `usercentrics-ui`) must already be published on CocoaPods trunk / Maven before you start, and the CHANGELOG entry for the new version is normally written by the user beforehand. Verify both before touching anything (see checklist). + +### 1. Pre-flight checklist + +- [ ] Confirm CHANGELOG.md already has a `### X.Y.Z – , ` section at the top (see format below). If missing, ask — don't invent changelog content. +- [ ] Confirm you're on a dedicated branch (e.g. `bump/X.Y.Z`), never commit version bumps directly to `master`. +- [ ] Confirm the target native SDK version is actually resolvable: + - iOS: `bundle exec pod repo update` inside `sample/ios`, then check `~/.cocoapods/repos/cocoapods/Specs/e/f/5/UsercentricsUI/X.Y.Z/` exists (or search CocoaPods trunk). + - Android: the version must exist on Maven Central / the configured repo for `com.usercentrics.sdk:usercentrics-ui`. + - If the native version isn't published yet, stop and say so — bumping to an unpublished version will make `pod install` and Gradle sync fail in CI. + +### 2. Files that encode the version number (bump ALL of them, in this order) + +| File | Field(s) | +|---|---| +| `package.json` | `"version"` **and** `"iosPackageVersion"` (both, they can diverge conceptually but are bumped together) | +| `android/build.gradle.kts` | `val usercentricsVersion = "X.Y.Z"` (line 1) | +| `package-lock.json` | regenerated automatically by `npm install` — don't hand-edit | +| `sample/ios/Podfile.lock` | regenerated by CocoaPods — don't hand-edit (see step 4) | + +CHANGELOG.md format (top of file, newest first): +``` +### X.Y.Z – Mon D, YYYY +## Features +* **[Component]** Description +## Fixes +* **[Component]** Description +## Chores +* **[Component]** Description +``` +`## Features` / `## Fixes` / `## Chores` sections are optional — omit any with nothing to report. + +### 3. Update package/gradle version strings + +Plain string edits — no tooling needed: +```bash +# package.json: bump "version" and "iosPackageVersion" +# android/build.gradle.kts: bump usercentricsVersion +``` + +### 4. Regenerate lockfiles + +```bash +npm install # refreshes package-lock.json "version" fields; also runs `yarn compile` via prepare +cd sample/ios +bundle exec pod repo update # fetch latest trunk specs (required if the native version was just published) +bundle exec pod update UsercentricsUI # bumps UsercentricsUI + Usercentrics + react-native-usercentrics in Podfile.lock +``` +Notes: +- `pod update UsercentricsUI` (not plain `pod install`) is required because the Podfile.lock has the *old* version pinned as a hard constraint — a plain `pod install` will refuse to move it and tell you to run `pod update `. +- The resulting `Podfile.lock` diff will include **a lot of unrelated `SPEC CHECKSUMS` churn** for `React-*` pods even though their versions don't change. This is expected and fine to commit as-is: CI's iOS job always runs `pod deintegrate && pod cache clean --all && bundle exec pod install --repo-update` from scratch (see `.github/workflows/ci.yml`), so whatever you commit here gets regenerated by CI anyway — it is not validated byte-for-byte. Sanity-check it's deterministic by running `pod install` a second time and confirming no further diff. +- The `sample` app's own `package-lock.json`/`node_modules` are independent from the root ones and are normally **not** touched by a version bump (the sample doesn't pin the SDK version itself, it consumes it via a local path dependency). + +### 5. Run tests before pushing (don't skip — this is what keeps CI green) + +```bash +npm run compile # tsc -p . — must be clean +npm test # jest src/__tests__/index.test.ts — must be 100% passing +``` +- `npm run lint` currently has **57 pre-existing errors / ~4700 warnings on master** — this is known tech debt, unrelated to version bumps. Don't try to fix it as part of a release; just confirm the error count didn't *increase* vs. `master` (`git stash` and re-run to compare if in doubt). +- Full native test suites (`xcodebuild test` on `sampleTests`, `./gradlew koverXmlReport`) are what CI's `test-ios` / `test-android` jobs run — they're slow (multi-minute Xcode builds) and CI already re-resolves pods from scratch, so don't try to fully reproduce them locally as a gate. It's fine to let CI be the source of truth for those; just make sure the pod resolution step (`pod install`) itself succeeds locally first, since that's the part a bad version bump most commonly breaks. +- `scripts/assert_export.sh` (run in CI's `test-rn` job) checks every file in `src/models/` is re-exported from `src/models/index.tsx` — irrelevant to a pure version bump but worth knowing it exists if a release also lands new model files. + +### 6. Commit + +Match the existing convention exactly (see `cb74f4b2`, `3380b40`, `7b13655`, `ae95d6e` for precedent): +``` +Release: X.Y.Z + +Co-Authored-By: Claude Sonnet 5 +``` +Files in the commit: `CHANGELOG.md`, `package.json`, `package-lock.json`, `android/build.gradle.kts`, `sample/ios/Podfile.lock`. Nothing else — a release commit should never carry unrelated code changes. + +### 7. After merge + +Actual `npm publish` happens via `.github/workflows/release.yml`, triggered by a **GitHub Release being created** (not by this commit landing on master). That step is out of scope for the bump itself — flag it to the user rather than trying to trigger it. + +## CI reference (`.github/workflows/ci.yml`) + +Runs on every PR into `master`: +- `test-rn` (ubuntu): `yarn install --frozen-lockfile` → `yarn compile` → `yarn test` → `scripts/assert_export.sh` +- `test-ios` (macos-14, Xcode 16.1): fresh `pod deintegrate` + `pod cache clean --all` + `pod install --repo-update`, then `xcodebuild test` on the `sampleTests` scheme +- `test-android` (macOS-14, Java 17): `./gradlew :react-native-usercentrics:koverXmlReport` + +`RCT_NEW_ARCH_ENABLED` in the iOS job's `env:` is actually irrelevant — `sample/ios/Podfile` hardcodes `$RCT_NEW_ARCH_ENABLED = true` and sets `ENV['RCT_NEW_ARCH_ENABLED']` *from* that, not the other way round. Always assume New Architecture (Fabric + TurboModules) is on for both local and CI pod resolution. diff --git a/android/build.gradle.kts b/android/build.gradle.kts index 0158856..6d23d4a 100644 --- a/android/build.gradle.kts +++ b/android/build.gradle.kts @@ -1,4 +1,4 @@ -val usercentricsVersion = "2.28.2" +val usercentricsVersion = "2.29.1" val reactNativeVersion = "+" fun BooleanProperty(name: String): Boolean { diff --git a/ios/Manager/UsercentricsManager.swift b/ios/Manager/UsercentricsManager.swift index d109560..d62a55a 100644 --- a/ios/Manager/UsercentricsManager.swift +++ b/ios/Manager/UsercentricsManager.swift @@ -33,8 +33,8 @@ public protocol UsercentricsManager { func acceptAllForTCF(fromLayer: TCFDecisionUILayer, consentType: UsercentricsConsentType) -> [UsercentricsServiceConsent] func acceptAll(consentType: UsercentricsConsentType) -> [UsercentricsServiceConsent] - func denyAllForTCF(fromLayer: TCFDecisionUILayer, consentType: UsercentricsConsentType, unsavedPurposeLIDecisions: [KotlinInt: KotlinBoolean]?, unsavedVendorLIDecisions: [KotlinInt: KotlinBoolean]?) -> [UsercentricsServiceConsent] - func denyAll(consentType: UsercentricsConsentType) -> [UsercentricsServiceConsent] + func denyAllForTCF(fromLayer: TCFDecisionUILayer, consentType: UsercentricsConsentType, unsavedPurposeLIDecisions: [KotlinInt: KotlinBoolean]?, unsavedVendorLIDecisions: [KotlinInt: KotlinBoolean]?, unsavedServiceDecisions: [String: KotlinBoolean]?) -> [UsercentricsServiceConsent] + func denyAll(consentType: UsercentricsConsentType, unsavedServiceDecisions: [String: KotlinBoolean]?) -> [UsercentricsServiceConsent] func saveDecisionsForTCF(tcfDecisions: TCFUserDecisions, fromLayer: TCFDecisionUILayer, @@ -137,12 +137,12 @@ final class UsercentricsManagerImplementation: UsercentricsManager { return UsercentricsCore.shared.acceptAll(consentType: consentType) } - func denyAllForTCF(fromLayer: TCFDecisionUILayer, consentType: UsercentricsConsentType, unsavedPurposeLIDecisions: [KotlinInt: KotlinBoolean]?, unsavedVendorLIDecisions: [KotlinInt: KotlinBoolean]?) -> [UsercentricsServiceConsent] { - return UsercentricsCore.shared.denyAllForTCF(fromLayer: fromLayer, consentType: consentType, unsavedPurposeLIDecisions: unsavedPurposeLIDecisions, unsavedVendorLIDecisions: unsavedVendorLIDecisions) + func denyAllForTCF(fromLayer: TCFDecisionUILayer, consentType: UsercentricsConsentType, unsavedPurposeLIDecisions: [KotlinInt: KotlinBoolean]?, unsavedVendorLIDecisions: [KotlinInt: KotlinBoolean]?, unsavedServiceDecisions: [String: KotlinBoolean]?) -> [UsercentricsServiceConsent] { + return UsercentricsCore.shared.denyAllForTCF(fromLayer: fromLayer, consentType: consentType, unsavedPurposeLIDecisions: unsavedPurposeLIDecisions, unsavedVendorLIDecisions: unsavedVendorLIDecisions, unsavedServiceDecisions: unsavedServiceDecisions) } - func denyAll(consentType: UsercentricsConsentType) -> [UsercentricsServiceConsent] { - return UsercentricsCore.shared.denyAll(consentType: consentType) + func denyAll(consentType: UsercentricsConsentType, unsavedServiceDecisions: [String: KotlinBoolean]?) -> [UsercentricsServiceConsent] { + return UsercentricsCore.shared.denyAll(consentType: consentType, unsavedServiceDecisions: unsavedServiceDecisions) } func saveDecisionsForTCF(tcfDecisions: TCFUserDecisions, fromLayer: TCFDecisionUILayer, serviceDecisions: [UserDecision], consentType: UsercentricsConsentType) -> [UsercentricsServiceConsent] { diff --git a/ios/RNUsercentricsModule.swift b/ios/RNUsercentricsModule.swift index 96ef537..21f7036 100644 --- a/ios/RNUsercentricsModule.swift +++ b/ios/RNUsercentricsModule.swift @@ -202,7 +202,8 @@ class RNUsercentricsModule: RCTEventEmitter { fromLayer: .initialize(from: Int(fromLayer)), consentType: .initialize(from: Int(consentType)), unsavedPurposeLIDecisions: extractLIDecisionsMap(unsavedPurposeLIDecisions), - unsavedVendorLIDecisions: extractLIDecisionsMap(unsavedVendorLIDecisions) + unsavedVendorLIDecisions: extractLIDecisionsMap(unsavedVendorLIDecisions), + unsavedServiceDecisions: nil ) resolve(services.toListOfDictionary()) } @@ -220,7 +221,7 @@ class RNUsercentricsModule: RCTEventEmitter { @objc func denyAll(_ consentType: Double, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void { - let services = usercentricsManager.denyAll(consentType: .initialize(from: Int(consentType))) + let services = usercentricsManager.denyAll(consentType: .initialize(from: Int(consentType)), unsavedServiceDecisions: nil) resolve(services.toListOfDictionary()) } diff --git a/package-lock.json b/package-lock.json index 27e4984..5516ec9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@usercentrics/react-native-sdk", - "version": "2.28.2", + "version": "2.29.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@usercentrics/react-native-sdk", - "version": "2.28.2", + "version": "2.29.1", "license": "SEE LICENSE IN LICENSE", "devDependencies": { "@babel/core": "^7.25.10", diff --git a/package.json b/package.json index 54c25d4..a34a2b0 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { "name": "@usercentrics/react-native-sdk", - "version": "2.28.2", + "version": "2.29.1", "description": "Usercentrics SDK", "homepage": "https://usercentrics.com", "main": "lib/index.js", "types": "lib/index.d.ts", "author": "Usercentrics ", "iosPackageName": "react-native-usercentrics", - "iosPackageVersion": "2.28.2", + "iosPackageVersion": "2.29.1", "license": "SEE LICENSE IN LICENSE", "files": [ "android", diff --git a/sample/ios/Podfile.lock b/sample/ios/Podfile.lock index f7ff60c..3bd39a9 100644 --- a/sample/ios/Podfile.lock +++ b/sample/ios/Podfile.lock @@ -1924,7 +1924,7 @@ PODS: - ReactCommon/turbomodule/core - SocketRocket - Yoga - - react-native-usercentrics (2.28.2): + - react-native-usercentrics (2.29.1): - boost - DoubleConversion - fast_float @@ -1951,7 +1951,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - SocketRocket - - UsercentricsUI (= 2.28.2) + - UsercentricsUI (= 2.29.1) - Yoga - react-native-webview (13.16.1): - boost @@ -2546,9 +2546,9 @@ PODS: - SocketRocket - Yoga - SocketRocket (0.7.1) - - Usercentrics (2.28.2) - - UsercentricsUI (2.28.2): - - Usercentrics (= 2.28.2) + - Usercentrics (2.29.1) + - UsercentricsUI (2.29.1): + - Usercentrics (= 2.29.1) - Yoga (0.0.0) DEPENDENCIES: @@ -2822,70 +2822,70 @@ SPEC CHECKSUMS: RCTTypeSafety: 4aefa8328ab1f86da273f08517f1f6b343f6c2cc React: 2073376f47c71b7e9a0af7535986a77522ce1049 React-callinvoker: 751b6f2c83347a0486391c3f266f291f0f53b27e - React-Core: 7195661f0b48e7ea46c3360ccb575288a20c932c - React-CoreModules: 14f0054ab46000dd3b816d6528af3bd600d82073 - React-cxxreact: 7f602425c63096c398dac13cd7a300efd7c281ae + React-Core: dff5d29973349b11dd6631c9498456d75f846d5e + React-CoreModules: c0ae04452e4c5d30e06f8e94692a49107657f537 + React-cxxreact: 376fd672c95dfb64ad5cc246e6a1e9edb78dec4c React-debug: d4955c86870792887ed695df6ebf0e94e39dc7e1 - React-defaultsnativemodule: e741702f0e585c2f252cf1797ae7556312a5e43f - React-domnativemodule: 71832948d5efe4231231929f3ab8fb43c60e64be - React-Fabric: 40b52987bbf49a5eb3963d69eb79ee5fb474497d - React-FabricComponents: ac181f57440b220bc5c0c73a213c8f0beb4b402c - React-FabricImage: c32725d2935166d14fb6a0248ad5eec890a6665b - React-featureflags: f9cadeda57aa490c9c7a1df9af6866ef68bbddf6 - React-featureflagsnativemodule: 2c4196feb481fe502e4549bf8cff78cb98514b59 - React-graphics: b9a2c17b8baafe92ab5aad8ba940c30428cf9c99 - React-hermes: 0a167bbb02c242664745e82154578c64e90a88e5 - React-idlecallbacksnativemodule: 0950653cf076a6f98fe33403a70f9ab8506940bc - React-ImageManager: f2f1f5496db3912ebbc166701a381cea102123fd - React-jserrorhandler: ca36f91ee924e45aee9c14e5529ef7b94dcbfb8f - React-jsi: 9c27d27d3007b73c702ad3fd5a6166557c741020 - React-jsiexecutor: 2b24f4ed4026344a27f717bf947a434cbbeeff7a - React-jsinspector: 4bba4426916dbad83fd71eef70350cdf6bac70d1 - React-jsinspectorcdp: 2bde8377dc70d07c213c270135aaf3e9b660d6df - React-jsinspectornetwork: 25a94605232a7f5b9e74f54a1422a69baecf0517 - React-jsinspectortracing: ccae54ad4669316451af1297cc6cbd731a098ca5 - React-jsitooling: 754bebd7e20c271797bfa0df835b33dacfbf4821 - React-jsitracing: 339c27481f2fa42c0a71afcec86cf46022fdbf20 - React-logger: 1767babce2d28c3251039ce05556714a2c8c6ded - React-Mapbuffer: f84e59c14ff145295fbd029c5be16805aabe98d2 - React-microtasksnativemodule: 584eb07c9b1f1e684fe63b7fae61ed865f8f228f - react-native-safe-area-context: 7e0ba374906d8f5009aaf96cd19d4866d8de342b - react-native-usercentrics: 581b7026e7cc7d6a14a18ee1ee3f5f1add8f81b2 - react-native-webview: 21fdd62caca650645e429b4a84941626612616ef - React-NativeModulesApple: dcfbe72c5a47baec0699a2935c080b7de0c8657b + React-defaultsnativemodule: bd2b805c6daa85d430d034aa748544b377ada152 + React-domnativemodule: b5c04a4a74ed9c3cb25adc72583b017868600464 + React-Fabric: 93a9ff378f1edf29e9a22a24ad55a1be061e7985 + React-FabricComponents: 83bd54366d4ecb8bec563aa1a78d49915763d503 + React-FabricImage: 8bcd88e553047d4ed5c7ea3def8d6c0e3dd88cfc + React-featureflags: 4ea691ab154d505277859416aa226ae32edeef5f + React-featureflagsnativemodule: b8f00b01436294a30dc62fb5e50b70aa3910309c + React-graphics: d6207795fe822668daeb9c6e1f1470a8500d9eec + React-hermes: fcbdc45ecf38259fe3b12642bd0757c52270a107 + React-idlecallbacksnativemodule: f390a518e1a862453f45f86a1bc248350634d858 + React-ImageManager: acb99e093632b7fc2953dd45f2abaeeea2d9588e + React-jserrorhandler: 958ab9afbe7acdbfe8ca225f7503313409b1319a + React-jsi: 59ec3190dd364cca86a58869e7755477d2468948 + React-jsiexecutor: b87d78a2e8dd7a6f56e9cdac038da45de98c944f + React-jsinspector: 9c33e0c4eeeb10a23b61c4501947b57977980e0e + React-jsinspectorcdp: d7b2c3feddd3669f0eaad2ac1e0f7afbc1d1cf18 + React-jsinspectornetwork: 696d0cf07016e69c053deffba30003fa448904a3 + React-jsinspectortracing: 05d49cd8795db15a279eab6f7604dfa9fe9622f1 + React-jsitooling: 0f9894c3656c3c13d4fcfe6e1dc964fd340acf49 + React-jsitracing: dc11027f9e4e829d32bf17626ec831581ea05223 + React-logger: a3cb5b29c32b8e447b5a96919340e89334062b48 + React-Mapbuffer: e4a65db5f4df53369f39558c0cf2f480f6d3d6c7 + React-microtasksnativemodule: 86334c5c06315e0bccb7b6e6f2c905e92f98b615 + react-native-safe-area-context: eda63a662750758c1fdd7e719c9f1026c8d161cb + react-native-usercentrics: 8cd13b2cfe938140f93bc9296ac764a1d5ae4f02 + react-native-webview: 83c663c5bdf1357d3e7c00986260cb888ea0e328 + React-NativeModulesApple: 8c7eb6057b00c191a11ad5ced41826ec5a0e4d78 React-oscompat: 93b5535ea7f7dff46aaee4f78309a70979bdde9d - React-perflogger: a03d913e3205b00aee4128082abe42fd45ce0c98 - React-performancetimeline: e07fcee93986259c74a5be1a98770ed82086fe5b + React-perflogger: 5536d2df3d18fe0920263466f7b46a56351c0510 + React-performancetimeline: c6c9393c1a0453a51e1852e3531defe60790b36c React-RCTActionSheet: 42195ae666e6d79b4af2346770f765b7c29435b9 - React-RCTAnimation: 5c10527683128c56ff2c09297fb080f7c35bd293 - React-RCTAppDelegate: c616bd5b0d12f0b21dfacee9cd2d512c6df013aa - React-RCTBlob: 6e3757bdd7dce6fd9788c0dd675fd6b6c432db9d - React-RCTFabric: 25825d88450a5a076f8a31282f3ad745741283f4 - React-RCTFBReactNativeSpec: 672c5e8f3b94bd17979df3ef27ef84bfd4317a5a - React-RCTImage: a3482fe1ae562d1bab08b42d4670a7c9a21813cd - React-RCTLinking: d82b9adb141aef9d2b38d446b837ae7017ab60aa - React-RCTNetwork: fa9350dd99354c5695964f589bd4790bdd4f6a85 - React-RCTRuntime: c52d15ec0e57604245394a1dbef4eb6994716568 - React-RCTSettings: b7f4a03f44dba1d3a4dc6770843547b203ca9129 - React-RCTText: 91dc597a5f6b27fd1048bb287c41ea05eeca9333 - React-RCTVibration: 27b09ddf74bddfa30a58d20e48f885ea6ed6c9d9 + React-RCTAnimation: fa103ccc3503b1ed8dedca7e62e7823937748843 + React-RCTAppDelegate: 665d4baf19424cef08276e9ac0d8771eec4519f9 + React-RCTBlob: 0fa9530c255644db095f2c4fd8d89738d9d9ecc0 + React-RCTFabric: 95eb4a92c5c166e21bae07231d327174e56f202d + React-RCTFBReactNativeSpec: fd66225b71f902a8bfa939fb5f7ec743958298df + React-RCTImage: ba824e61ce2e920a239a65d130b83c3a1d426dff + React-RCTLinking: d2dc199c37e71e6f505d9eca3e5c33be930014d4 + React-RCTNetwork: 87137d4b9bd77e5068f854dd5c1f30d4b072faf6 + React-RCTRuntime: b10bd5e5506af0d6205c4101dd1560fe7beead95 + React-RCTSettings: 71f5c7fd7b5f4e725a4e2114a4b4373d0e46048f + React-RCTText: b94d4699b49285bee22b8ebf768924d607eccee3 + React-RCTVibration: 6e3993c4f6c36a3899059f9a9ead560ddaf5a7d7 React-rendererconsistency: 612d0f6603d9837bb1236d7fd5194203b35c8799 - React-renderercss: 5cc9e5e6732dc124dee16b7ab8f48e0b60b3f31d - React-rendererdebug: 224a1beff9e5d5bc537e72b454135006a5c02a52 - React-RuntimeApple: 9bd8789d7b1d0b5502911da80943b3b2fddfe753 - React-RuntimeCore: 9277538145df1bf2c31432870a308357e34098b2 - React-runtimeexecutor: 69ea4689569738c4ecc4086fde2b30967e19101f - React-RuntimeHermes: 8f59a450f31b741dcf2cc979cb0568a30c5fe1a0 - React-runtimescheduler: 75dfc03be8e0a25751a162acb4ff96be4cc020dc - React-timing: d85ab9efe229cc4145f8f21be0af6c150d3d4682 - React-utils: bb55410c0db3a7f57b9518e3dcf76ab77a0a157e - ReactAppDependencyProvider: b20fba6c3d091a393925890009999472c8f94d95 - ReactCodegen: 07322ec16b66c5f5d7ce7a7cadaba401ecb81908 - ReactCommon: a42100667ef42807c485a579847a5ec2c99e0a82 - RNScreens: 656e050942ae9445f5cc45d05d57f13ce7a4c8e4 + React-renderercss: e5c2c3b84976f7a587cde8423c671db07a6a77da + React-rendererdebug: cc7a6131733605b8897754f72c0c35c79f77da9e + React-RuntimeApple: 3f96102fc1ebf738d36719cdce5422a5769293fb + React-RuntimeCore: f05563107927f155180dfa008fed2ac1316a6aec + React-runtimeexecutor: dd3ec3b76761b43e7b37d07a70de91fc1dd24e7e + React-RuntimeHermes: 7fcb384acc111ea21bcffe2e4a15f31b58bb702e + React-runtimescheduler: 7d2eaa4e7d652a391f47df7ff510260413429bd9 + React-timing: f5d4ba74be96a24b9b2a1a910142ed14e03013d9 + React-utils: eb92d1db56a9bb5911b2c77fb4c2e8d331c8b9dd + ReactAppDependencyProvider: 433ddfb4536948630aadd5bd925aff8a632d2fe3 + ReactCodegen: 2cfa890e84ecf7f3a708f1ed9c0f2c0b22a23c9a + ReactCommon: e9ab32f1d1482d207867b4fdd139361302b9dcc6 + RNScreens: e902eba58a27d3ad399a495d578e8aba3ea0f490 SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 - Usercentrics: d582dd2a4d474f7521fb1c69b0ad2e36306c8f60 - UsercentricsUI: 82c26e8bd40ad89fd4106b53f45ba773eb742429 + Usercentrics: 1234eaa46bfb50c4645226ed0c617ef34967e890 + UsercentricsUI: f304cc98ade660138a90089b7289cb2e09e58d44 Yoga: 9b30b783a17681321b52ac507a37219d7d795ace PODFILE CHECKSUM: 8d257452e9e69d13384a99ee3cd38b42636521da diff --git a/sample/ios/sampleTests/Fake/FakeUsercentricsManager.swift b/sample/ios/sampleTests/Fake/FakeUsercentricsManager.swift index 43e59f7..2f1841f 100644 --- a/sample/ios/sampleTests/Fake/FakeUsercentricsManager.swift +++ b/sample/ios/sampleTests/Fake/FakeUsercentricsManager.swift @@ -170,19 +170,23 @@ final class FakeUsercentricsManager: UsercentricsManager { var denyAllForTCFFromLayer: TCFDecisionUILayer? var denyAllForTCFUnsavedPurposeLIDecisions: [KotlinInt: KotlinBoolean]? var denyAllForTCFUnsavedVendorLIDecisions: [KotlinInt: KotlinBoolean]? + var denyAllForTCFUnsavedServiceDecisions: [String: KotlinBoolean]? var denyAllForTCFResponse: [UsercentricsServiceConsent]? - func denyAllForTCF(fromLayer: TCFDecisionUILayer, consentType: UsercentricsConsentType, unsavedPurposeLIDecisions: [KotlinInt: KotlinBoolean]?, unsavedVendorLIDecisions: [KotlinInt: KotlinBoolean]?) -> [UsercentricsServiceConsent] { + func denyAllForTCF(fromLayer: TCFDecisionUILayer, consentType: UsercentricsConsentType, unsavedPurposeLIDecisions: [KotlinInt: KotlinBoolean]?, unsavedVendorLIDecisions: [KotlinInt: KotlinBoolean]?, unsavedServiceDecisions: [String: KotlinBoolean]?) -> [UsercentricsServiceConsent] { self.denyAllForTCFConsentType = consentType self.denyAllForTCFFromLayer = fromLayer self.denyAllForTCFUnsavedPurposeLIDecisions = unsavedPurposeLIDecisions self.denyAllForTCFUnsavedVendorLIDecisions = unsavedVendorLIDecisions + self.denyAllForTCFUnsavedServiceDecisions = unsavedServiceDecisions return denyAllForTCFResponse! } var denyAllConsentType: UsercentricsConsentType? + var denyAllUnsavedServiceDecisions: [String: KotlinBoolean]? var denyAllResponse: [UsercentricsServiceConsent]? - func denyAll(consentType: UsercentricsConsentType) -> [UsercentricsServiceConsent] { + func denyAll(consentType: UsercentricsConsentType, unsavedServiceDecisions: [String: KotlinBoolean]?) -> [UsercentricsServiceConsent] { self.denyAllConsentType = consentType + self.denyAllUnsavedServiceDecisions = unsavedServiceDecisions return denyAllResponse! } diff --git a/sample/ios/sampleTests/Mock/CMPData+Mock.swift b/sample/ios/sampleTests/Mock/CMPData+Mock.swift index 7b138f3..23fc232 100644 --- a/sample/ios/sampleTests/Mock/CMPData+Mock.swift +++ b/sample/ios/sampleTests/Mock/CMPData+Mock.swift @@ -104,7 +104,8 @@ extension UsercentricsService { isAutoUpdateAllowed: true, disableLegalBasis: true, isEssential: true, - metadata: nil) + metadata: nil, + isExempt: false) } } @@ -434,6 +435,7 @@ extension ServiceConsentTemplate { static func mock() -> ServiceConsentTemplate { return .init(isDeactivated: true, defaultConsentStatus: true, + isExempt: false, templateId: "templateId", version: "version", categorySlug: "categorySlug", @@ -452,6 +454,7 @@ extension SubConsentTemplate { static func mock() -> SubConsentTemplate { return .init(isDeactivated: true, defaultConsentStatus: true, + isExempt: false, templateId: "templateId", version: "version", categorySlug: "categorySlug", @@ -468,7 +471,8 @@ extension UsercentricsCategory { label: "label", description: "description", isEssential: true, - isHidden: true) + isHidden: true, + isExempt: false) } }