From a4d7beaf5d1780fdae4b1d89aa01f94b9bbe7922 Mon Sep 17 00:00:00 2001 From: asadraza-usercentrics Date: Fri, 8 May 2026 17:01:58 +0100 Subject: [PATCH 1/7] feat(MSDK-3663): add Firebase mediation test infrastructure to example app --- example/android/app/build.gradle | 6 +- example/android/app/google-services.json | 121 ++++++++++++++++++ .../android/app/src/main/AndroidManifest.xml | 6 + example/android/build.gradle | 1 + example/ios/Podfile | 6 + example/ios/Podfile.lock | 119 ++++++++++++++++- example/ios/Runner.xcodeproj/project.pbxproj | 52 ++++---- example/ios/Runner/AppDelegate.swift | 2 + example/ios/Runner/GoogleService-Info.plist | 32 +++++ example/ios/Runner/Info.plist | 2 + example/lib/main.dart | 14 +- example/pubspec.lock | 8 +- 12 files changed, 332 insertions(+), 37 deletions(-) create mode 100644 example/android/app/google-services.json create mode 100644 example/ios/Runner/GoogleService-Info.plist diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index ff67f652..4a897c30 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -2,6 +2,7 @@ plugins { id "com.android.application" id "kotlin-android" id "dev.flutter.flutter-gradle-plugin" + id "com.google.gms.google-services" } def localProperties = new Properties() @@ -40,7 +41,7 @@ android { } defaultConfig { - applicationId "com.usercentrics.sdk.flutter_example" + applicationId "com.usercentrics.sdk.mediation.test" minSdk flutter.minSdkVersion targetSdk 34 versionCode flutterVersionCode.toInteger() @@ -62,4 +63,7 @@ flutter { dependencies { implementation "androidx.multidex:multidex:2.0.1" + + implementation platform('com.google.firebase:firebase-bom:33.13.0') + implementation 'com.google.firebase:firebase-analytics' } diff --git a/example/android/app/google-services.json b/example/android/app/google-services.json new file mode 100644 index 00000000..d990c3eb --- /dev/null +++ b/example/android/app/google-services.json @@ -0,0 +1,121 @@ +{ + "project_info": { + "project_number": "562107654987", + "firebase_url": "https://in-app-sdk.firebaseio.com", + "project_id": "in-app-sdk", + "storage_bucket": "in-app-sdk.firebasestorage.app" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:562107654987:android:6bb088ad92ea16babefece", + "android_client_info": { + "package_name": "com.example.consentmodetest" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyBHshOoQxVLvoKysTREsnFMDKfJmyMTteU" + }, + { + "current_key": "AIzaSyDcjIcogDtyWxA5gfF2nC4Qn9lwQUZjuCs" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:562107654987:android:35ce647b6cfbf31bbefece", + "android_client_info": { + "package_name": "com.test.gorgonzola" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyBHshOoQxVLvoKysTREsnFMDKfJmyMTteU" + }, + { + "current_key": "AIzaSyDcjIcogDtyWxA5gfF2nC4Qn9lwQUZjuCs" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:562107654987:android:b6b77734769e9401befece", + "android_client_info": { + "package_name": "com.usercentrics.inappsdk" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyBHshOoQxVLvoKysTREsnFMDKfJmyMTteU" + }, + { + "current_key": "AIzaSyDcjIcogDtyWxA5gfF2nC4Qn9lwQUZjuCs" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:562107654987:android:db95a2358719b371befece", + "android_client_info": { + "package_name": "com.usercentrics.mediation.test" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyBHshOoQxVLvoKysTREsnFMDKfJmyMTteU" + }, + { + "current_key": "AIzaSyDcjIcogDtyWxA5gfF2nC4Qn9lwQUZjuCs" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:562107654987:android:48c16f389df9d9f9befece", + "android_client_info": { + "package_name": "com.usercentrics.sdk.mediation.test" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyBHshOoQxVLvoKysTREsnFMDKfJmyMTteU" + }, + { + "current_key": "AIzaSyDcjIcogDtyWxA5gfF2nC4Qn9lwQUZjuCs" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 8687b253..de5c0aa6 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -4,6 +4,12 @@ android:label="Usercentrics Flutter Sample" android:icon="@mipmap/ic_launcher" android:name="androidx.multidex.MultiDexApplication" > + + + + + + '../../../mobile-sdk/platforms/ios/UsercentricsUI' + + # Firebase — required to test MSDK-3667 (setAnalyticsCollectionEnabled via NSInvocation) + pod 'FirebaseAnalytics' + target 'RunnerTests' do inherit! :complete end diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 5997b60e..584cb8ac 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,5 +1,93 @@ PODS: + - FirebaseAnalytics (11.15.0): + - FirebaseAnalytics/Default (= 11.15.0) + - FirebaseCore (~> 11.15.0) + - FirebaseInstallations (~> 11.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseAnalytics/Default (11.15.0): + - FirebaseCore (~> 11.15.0) + - FirebaseInstallations (~> 11.0) + - GoogleAppMeasurement/Default (= 11.15.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - FirebaseCore (11.15.0): + - FirebaseCoreInternal (~> 11.15.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/Logger (~> 8.1) + - FirebaseCoreInternal (11.15.0): + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - FirebaseInstallations (11.15.0): + - FirebaseCore (~> 11.15.0) + - GoogleUtilities/Environment (~> 8.1) + - GoogleUtilities/UserDefaults (~> 8.1) + - PromisesObjC (~> 2.4) - Flutter (1.0.0) + - GoogleAdsOnDeviceConversion (2.1.0): + - GoogleUtilities/Logger (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Core (11.15.0): + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/Default (11.15.0): + - GoogleAdsOnDeviceConversion (= 2.1.0) + - GoogleAppMeasurement/Core (= 11.15.0) + - GoogleAppMeasurement/IdentitySupport (= 11.15.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleAppMeasurement/IdentitySupport (11.15.0): + - GoogleAppMeasurement/Core (= 11.15.0) + - GoogleUtilities/AppDelegateSwizzler (~> 8.1) + - GoogleUtilities/MethodSwizzler (~> 8.1) + - GoogleUtilities/Network (~> 8.1) + - "GoogleUtilities/NSData+zlib (~> 8.1)" + - nanopb (~> 3.30910.0) + - GoogleUtilities/AppDelegateSwizzler (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Privacy + - GoogleUtilities/Environment (8.1.0): + - GoogleUtilities/Privacy + - GoogleUtilities/Logger (8.1.0): + - GoogleUtilities/Environment + - GoogleUtilities/Privacy + - GoogleUtilities/MethodSwizzler (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/Network (8.1.0): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Privacy + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (8.1.0)": + - GoogleUtilities/Privacy + - GoogleUtilities/Privacy (8.1.0) + - GoogleUtilities/Reachability (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - GoogleUtilities/UserDefaults (8.1.0): + - GoogleUtilities/Logger + - GoogleUtilities/Privacy + - nanopb (3.30910.0): + - nanopb/decode (= 3.30910.0) + - nanopb/encode (= 3.30910.0) + - nanopb/decode (3.30910.0) + - nanopb/encode (3.30910.0) + - PromisesObjC (2.4.0) - Usercentrics (2.26.2) - usercentrics_sdk (2.26.2): - Flutter @@ -11,30 +99,51 @@ PODS: - FlutterMacOS DEPENDENCIES: + - FirebaseAnalytics - Flutter (from `Flutter`) - usercentrics_sdk (from `.symlinks/plugins/usercentrics_sdk/ios`) + - UsercentricsUI (from `../../../mobile-sdk/platforms/ios/UsercentricsUI`) - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/darwin`) SPEC REPOS: trunk: + - FirebaseAnalytics + - FirebaseCore + - FirebaseCoreInternal + - FirebaseInstallations + - GoogleAdsOnDeviceConversion + - GoogleAppMeasurement + - GoogleUtilities + - nanopb + - PromisesObjC - Usercentrics - - UsercentricsUI EXTERNAL SOURCES: Flutter: :path: Flutter usercentrics_sdk: :path: ".symlinks/plugins/usercentrics_sdk/ios" + UsercentricsUI: + :path: "../../../mobile-sdk/platforms/ios/UsercentricsUI" webview_flutter_wkwebview: :path: ".symlinks/plugins/webview_flutter_wkwebview/darwin" SPEC CHECKSUMS: + FirebaseAnalytics: 6433dfd311ba78084fc93bdfc145e8cb75740eae + FirebaseCore: efb3893e5b94f32b86e331e3bd6dadf18b66568e + FirebaseCoreInternal: 9afa45b1159304c963da48addb78275ef701c6b4 + FirebaseInstallations: 317270fec08a5d418fdbc8429282238cab3ac843 Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 - Usercentrics: add954fa1e0a1cfde768e350f895252b72bc6c1f - usercentrics_sdk: 73e1f87f065dbea395012fa2a09d81fc70ed68f1 - UsercentricsUI: c1491664512f56c68425da2d270d94ba48a470f9 + GoogleAdsOnDeviceConversion: 2be6297a4f048459e0ae17fad9bfd2844e10cf64 + GoogleAppMeasurement: 700dce7541804bec33db590a5c496b663fbe2539 + GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 + nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 + PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + Usercentrics: 26f9f31e4e83cc0de49c3913577c6a819ba172f8 + usercentrics_sdk: 6be3d30f8371353fbee168b7daf8b4a92d168d84 + UsercentricsUI: 2328bf9b211e381bd312e6cd1b0951e0515cbacb webview_flutter_wkwebview: 1821ceac936eba6f7984d89a9f3bcb4dea99ebb2 -PODFILE CHECKSUM: 723de1cf6e2f18b51eb3426c945e31134a750097 +PODFILE CHECKSUM: c29419e9a80f067fe8952f0a5d2bedf438aa08c8 COCOAPODS: 1.16.2 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index e2a4cdc7..56947d60 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + DA0000021CF9000F007C117D /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = DA0000011CF9000F007C117D /* GoogleService-Info.plist */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 17F28FC4AC3BF66FC4301149 /* Pods_Runner_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 760C9E4CB26E7DAC6C729A22 /* Pods_Runner_RunnerTests.framework */; }; 3453DCAF2B3D971200EFE874 /* GetAdditionalConsentModeBridgeTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3453DCAE2B3D971200EFE874 /* GetAdditionalConsentModeBridgeTest.swift */; }; @@ -70,6 +71,7 @@ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + DA0000011CF9000F007C117D /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 760C9E4CB26E7DAC6C729A22 /* Pods_Runner_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 773DA90C23F572C5E5B4A715 /* Pods-Runner-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-Runner-RunnerTests/Pods-Runner-RunnerTests.debug.xcconfig"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; @@ -190,6 +192,7 @@ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + DA0000011CF9000F007C117D /* GoogleService-Info.plist */, ); path = Runner; sourceTree = ""; @@ -252,7 +255,7 @@ 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 1F342D11C70C4597B5713902 /* [CP] Embed Pods Frameworks */, - ACEB877A4FF050D5B02BD9F9 /* [CP] Copy Pods Resources */, + 6AA24D08C3DF3E0B10B1AE84 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -272,7 +275,7 @@ A2DF520F2716C91700204F07 /* Frameworks */, A2DF52102716C91700204F07 /* Resources */, A6E8EE0276D65A197F751858 /* [CP] Embed Pods Frameworks */, - 874B1E5DDFFFAF8DA8696787 /* [CP] Copy Pods Resources */, + E16650957EA3675D6DBDF252 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -332,6 +335,7 @@ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + DA0000021CF9000F007C117D /* GoogleService-Info.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -400,21 +404,21 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 874B1E5DDFFFAF8DA8696787 /* [CP] Copy Pods Resources */ = { + 6AA24D08C3DF3E0B10B1AE84 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner-RunnerTests/Pods-Runner-RunnerTests-resources-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner-RunnerTests/Pods-Runner-RunnerTests-resources-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner-RunnerTests/Pods-Runner-RunnerTests-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; showEnvVarsInLog = 0; }; 9740EEB61CF901F6004384FC /* Run Script */ = { @@ -449,43 +453,43 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner-RunnerTests/Pods-Runner-RunnerTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - ACEB877A4FF050D5B02BD9F9 /* [CP] Copy Pods Resources */ = { + B2878DD7ABAFFBDED4E812A9 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Copy Pods Resources"; + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - B2878DD7ABAFFBDED4E812A9 /* [CP] Check Pods Manifest.lock */ = { + E16650957EA3675D6DBDF252 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner-RunnerTests/Pods-Runner-RunnerTests-resources-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + "${PODS_ROOT}/Target Support Files/Pods-Runner-RunnerTests/Pods-Runner-RunnerTests-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner-RunnerTests/Pods-Runner-RunnerTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -624,7 +628,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.usercentrics.sdk.usercentricsExample; + PRODUCT_BUNDLE_IDENTIFIER = com.usercentrics.sdk.mediation.test; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -757,7 +761,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.usercentrics.sdk.usercentricsExample; + PRODUCT_BUNDLE_IDENTIFIER = com.usercentrics.sdk.mediation.test; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -784,7 +788,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.usercentrics.sdk.usercentricsExample; + PRODUCT_BUNDLE_IDENTIFIER = com.usercentrics.sdk.mediation.test; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; diff --git a/example/ios/Runner/AppDelegate.swift b/example/ios/Runner/AppDelegate.swift index 62666446..7db7d3da 100644 --- a/example/ios/Runner/AppDelegate.swift +++ b/example/ios/Runner/AppDelegate.swift @@ -1,3 +1,4 @@ +import FirebaseCore import Flutter import UIKit @@ -7,6 +8,7 @@ import UIKit _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { + FirebaseApp.configure() GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } diff --git a/example/ios/Runner/GoogleService-Info.plist b/example/ios/Runner/GoogleService-Info.plist new file mode 100644 index 00000000..3d3f2510 --- /dev/null +++ b/example/ios/Runner/GoogleService-Info.plist @@ -0,0 +1,32 @@ + + + + + API_KEY + AIzaSyCbVPJwkNblldnnC6drkANOFNBR0pc16vc + GCM_SENDER_ID + 562107654987 + PLIST_VERSION + 1 + BUNDLE_ID + com.usercentrics.sdk.mediation.test + PROJECT_ID + in-app-sdk + STORAGE_BUCKET + in-app-sdk.firebasestorage.app + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:562107654987:ios:582fcab0c3093857befece + DATABASE_URL + https://in-app-sdk.firebaseio.com + + \ No newline at end of file diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist index 189e88d2..0f18f01b 100644 --- a/example/ios/Runner/Info.plist +++ b/example/ios/Runner/Info.plist @@ -2,6 +2,8 @@ + FIREBASE_ANALYTICS_COLLECTION_ENABLED + CADisableMinimumFrameDurationOnPhone CFBundleDevelopmentRegion diff --git a/example/lib/main.dart b/example/lib/main.dart index 59112c02..dd4e81d2 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -7,6 +7,15 @@ import 'build_your_own_ui.dart'; import 'customization_example_1.dart'; import 'customization_example_2.dart'; +// Build-time flag — shows the consent mediation toggle when true. +// Usage: flutter run --dart-define=MEDIATION_TEST=true +// Omit (or false) for normal builds — safe to publish. +const bool _kMediationTestEnabled = bool.fromEnvironment('MEDIATION_TEST', defaultValue: true); + +// Settings ID for the sample app. When testing consent mediation this must be a +// settings ID that has the target 3rd-party SDKs configured in the Usercentrics dashboard. +const String _kSettingsId = 'Yi9N3aXia'; + void main() { WidgetsFlutterBinding.ensureInitialized(); runApp(const MyApp()); @@ -35,7 +44,6 @@ class HomePage extends StatefulWidget { class HomePageState extends State { _SdkStatus _sdkStatus = _SdkStatus.idle; String? _statusMessage; - void _initializeUsercentrics() async { setState(() { _sdkStatus = _SdkStatus.loading; @@ -44,8 +52,9 @@ class HomePageState extends State { try { Usercentrics.initialize( - settingsId: 'Yi9N3aXia', + settingsId: _kSettingsId, loggerLevel: UsercentricsLoggerLevel.debug, + consentMediation: _kMediationTestEnabled, ); final status = await Usercentrics.status; @@ -177,7 +186,6 @@ class HomePageState extends State { ), ), ), - // ── END TEMPORARY ────────────────────────────────────────────── const SizedBox(height: 16), ElevatedButton( onPressed: isSdkReady ? () => _showFirstLayer() : null, diff --git a/example/pubspec.lock b/example/pubspec.lock index db4e201f..25c147b9 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -111,10 +111,10 @@ packages: dependency: transitive description: name: matcher - sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6" + sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 url: "https://pub.dev" source: hosted - version: "0.12.18" + version: "0.12.19" material_color_utilities: dependency: transitive description: @@ -196,10 +196,10 @@ packages: dependency: transitive description: name: test_api - sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636" + sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a" url: "https://pub.dev" source: hosted - version: "0.7.9" + version: "0.7.10" usercentrics_sdk: dependency: "direct main" description: From 0b8ec31ba7841749230acbbe4bed4aef8442f088 Mon Sep 17 00:00:00 2001 From: asadraza-usercentrics Date: Fri, 8 May 2026 17:01:58 +0100 Subject: [PATCH 2/7] chore: untrack Firebase config files, fix dart format, and update example README --- example/.gitignore | 4 + example/README.md | 165 ++++++++++++++++++-- example/android/app/google-services.json | 121 -------------- example/ios/Runner/GoogleService-Info.plist | 32 ---- pubspec.lock | 16 +- 5 files changed, 163 insertions(+), 175 deletions(-) delete mode 100644 example/android/app/google-services.json delete mode 100644 example/ios/Runner/GoogleService-Info.plist diff --git a/example/.gitignore b/example/.gitignore index 1130e20d..add25a5e 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -72,3 +72,7 @@ app.*.symbols # Obfuscation related app.*.map.json + +# Firebase config files — kept locally, not committed +android/app/google-services.json +ios/Runner/GoogleService-Info.plist diff --git a/example/README.md b/example/README.md index b4d407a3..da240e76 100644 --- a/example/README.md +++ b/example/README.md @@ -1,18 +1,64 @@ -# Usercentrics SDK for Flutter - Quickstart +# Usercentrics SDK for Flutter — Example App -The goal of this project is to show how to use Usercentrics SDK inside of a Flutter application. +This app demonstrates how to integrate and test the Usercentrics SDK in a Flutter application, including consent mediation with Firebase Analytics. -## Instructions +--- -This project is a starting point for a Flutter application. +## Prerequisites -- Step 1: Clone the repository +- [Flutter SDK](https://docs.flutter.dev/get-started/install) installed +- For iOS: Xcode + CocoaPods (`gem install cocoapods`) +- For Android: Android Studio or a connected device/emulator -- Step 2: Get the dependencies by executing `flutter pub get` +--- -- Step 3: Run the application by executing `flutter run` +## Running the App (without Consent Mediation) -## Result +No Firebase setup is required for the standard flow. + +**Step 1 — Clone the repository** +```bash +git clone https://github.com/Usercentrics/flutter-sdk.git +cd flutter-sdk +``` + +**Step 2 — Install dependencies** +```bash +flutter pub get +``` + +**Step 3 — iOS only: install pods** + +> **Note:** The iOS Podfile includes a local path override for `UsercentricsUI` pointing to +> `../../../mobile-sdk/platforms/ios/UsercentricsUI`. This is used for testing local +> mobile-sdk changes without a full release. If you do not have the `mobile-sdk` repository +> checked out at that relative path, remove or comment out that line in `example/ios/Podfile` +> before running `pod install`: +> ```ruby +> # pod 'UsercentricsUI', :path => '../../../mobile-sdk/platforms/ios/UsercentricsUI' +> ``` + +```bash +cd example/ios && pod install && cd ../.. +``` + +**Step 4 — Run the app** +```bash +cd example && flutter run +``` + +> **Note:** Consent mediation is **enabled by default** in this example app +> (`_kMediationTestEnabled = true`). To run without mediation, pass the flag explicitly: +> ```bash +> flutter run --dart-define=MEDIATION_TEST=false +> ``` +> Without Firebase config files in place, the app will still run but Firebase will not +> initialise — you will see an error in the logs. Add the config files as described below +> to test mediation end-to-end. + +--- + +## App Features After running the app you should see a screen like this: @@ -20,17 +66,108 @@ After running the app you should see a screen like this: ### UsercentricsUI +The default Usercentrics-provided consent banner. + -### CustomUI +### Custom UI + +Build your own consent UI using the raw consent data from the SDK. -### Consent Mediation +### Customization Examples + +Two built-in examples (`Customization Example 1` and `Customization Example 2`) show how to customise the banner appearance — fonts, colours, button layouts, and layer settings — using `BannerSettings`. + +### Webview Integration + +Demonstrates how to inject the user's Usercentrics session data into a `WebView` so the Browser CMP can pick up the native consent without asking the user again. + +### GPP Testing + +A dedicated screen for testing the Global Privacy Platform (GPP) API: +- Fetch and display the encoded GPP string +- Fetch full GPP data (applicable sections and field values) +- Set consent values for specific GPP sections (e.g. `usnat`, `usfl`) +- Monitor real-time `onGppSectionChange` stream events + +--- + +## Running the App with Consent Mediation + +Consent mediation automatically forwards the user's consent decisions to integrated third-party SDKs (e.g. Firebase Analytics). Testing this requires Firebase to be configured in the app. + +### Step 1 — Create a Firebase project + +1. Go to the [Firebase Console](https://console.firebase.google.com) +2. Click **Add project** and follow the setup wizard +3. Once the project is created, register two apps (Android + iOS) in the next steps + +### Step 2 — Register the Android app and download `google-services.json` + +1. In your Firebase project, click **Add app** → select **Android** +2. Enter the package name: `com.usercentrics.sdk.mediation.test` +3. Click **Register app** +4. Download the `google-services.json` file +5. Place it at: + ``` + example/android/app/google-services.json + ``` + +### Step 3 — Register the iOS app and download `GoogleService-Info.plist` + +1. In your Firebase project, click **Add app** → select **iOS** +2. Enter the bundle ID: `com.usercentrics.sdk.mediation.test` +3. Click **Register app** +4. Download the `GoogleService-Info.plist` file +5. Place it at: + ``` + example/ios/Runner/GoogleService-Info.plist + ``` + +> **Note:** Both config files are excluded from version control (`.gitignore`) as they +> contain API keys. You must add them locally before running the app with mediation. + +### Step 4 — Run the app + +Since mediation is enabled by default, simply run: + +```bash +cd example && flutter run +``` + +To explicitly disable mediation: + +```bash +cd example && flutter run --dart-define=MEDIATION_TEST=false +``` + +### Step 5 — Test consent mediation + +1. Tap **Initialize SDK** — the Usercentrics CMP will appear +2. Accept or deny consent +3. Check the debug logs — you should see mediation output like: + ``` + [USERCENTRICS][DEBUG] [Mediation] Firebase - Consent applied successfully. + ``` + +> **Important:** Consent is persisted locally on the device. To re-test mediation from a +> clean state, clear the app data (Android) or uninstall and reinstall the app (iOS) +> before running again. + +--- + +## Settings ID + +The example app uses the settings ID `Yi9N3aXia` by default, configured in +`example/lib/main.dart`. To test with your own Usercentrics configuration, replace it +with your settings ID from the [Usercentrics Admin Interface](https://admin.usercentrics.eu). -You can enable and run the Consent Mediation example in this example by following the [documentation](https://usercentrics.com/docs/apps/features/consent-mediation/#enable-mediation). +--- -## Learn more +## Learn More -- Check out the full [documentation](https://docs.usercentrics.com/cmp_in_app_sdk). -- Check our [website](https://usercentrics.com). +- [Usercentrics Documentation](https://docs.usercentrics.com/cmp_in_app_sdk) +- [Consent Mediation Guide](https://usercentrics.com/docs/apps/features/consent-mediation/#enable-mediation) +- [Usercentrics Website](https://usercentrics.com) diff --git a/example/android/app/google-services.json b/example/android/app/google-services.json deleted file mode 100644 index d990c3eb..00000000 --- a/example/android/app/google-services.json +++ /dev/null @@ -1,121 +0,0 @@ -{ - "project_info": { - "project_number": "562107654987", - "firebase_url": "https://in-app-sdk.firebaseio.com", - "project_id": "in-app-sdk", - "storage_bucket": "in-app-sdk.firebasestorage.app" - }, - "client": [ - { - "client_info": { - "mobilesdk_app_id": "1:562107654987:android:6bb088ad92ea16babefece", - "android_client_info": { - "package_name": "com.example.consentmodetest" - } - }, - "oauth_client": [], - "api_key": [ - { - "current_key": "AIzaSyBHshOoQxVLvoKysTREsnFMDKfJmyMTteU" - }, - { - "current_key": "AIzaSyDcjIcogDtyWxA5gfF2nC4Qn9lwQUZjuCs" - } - ], - "services": { - "appinvite_service": { - "other_platform_oauth_client": [] - } - } - }, - { - "client_info": { - "mobilesdk_app_id": "1:562107654987:android:35ce647b6cfbf31bbefece", - "android_client_info": { - "package_name": "com.test.gorgonzola" - } - }, - "oauth_client": [], - "api_key": [ - { - "current_key": "AIzaSyBHshOoQxVLvoKysTREsnFMDKfJmyMTteU" - }, - { - "current_key": "AIzaSyDcjIcogDtyWxA5gfF2nC4Qn9lwQUZjuCs" - } - ], - "services": { - "appinvite_service": { - "other_platform_oauth_client": [] - } - } - }, - { - "client_info": { - "mobilesdk_app_id": "1:562107654987:android:b6b77734769e9401befece", - "android_client_info": { - "package_name": "com.usercentrics.inappsdk" - } - }, - "oauth_client": [], - "api_key": [ - { - "current_key": "AIzaSyBHshOoQxVLvoKysTREsnFMDKfJmyMTteU" - }, - { - "current_key": "AIzaSyDcjIcogDtyWxA5gfF2nC4Qn9lwQUZjuCs" - } - ], - "services": { - "appinvite_service": { - "other_platform_oauth_client": [] - } - } - }, - { - "client_info": { - "mobilesdk_app_id": "1:562107654987:android:db95a2358719b371befece", - "android_client_info": { - "package_name": "com.usercentrics.mediation.test" - } - }, - "oauth_client": [], - "api_key": [ - { - "current_key": "AIzaSyBHshOoQxVLvoKysTREsnFMDKfJmyMTteU" - }, - { - "current_key": "AIzaSyDcjIcogDtyWxA5gfF2nC4Qn9lwQUZjuCs" - } - ], - "services": { - "appinvite_service": { - "other_platform_oauth_client": [] - } - } - }, - { - "client_info": { - "mobilesdk_app_id": "1:562107654987:android:48c16f389df9d9f9befece", - "android_client_info": { - "package_name": "com.usercentrics.sdk.mediation.test" - } - }, - "oauth_client": [], - "api_key": [ - { - "current_key": "AIzaSyBHshOoQxVLvoKysTREsnFMDKfJmyMTteU" - }, - { - "current_key": "AIzaSyDcjIcogDtyWxA5gfF2nC4Qn9lwQUZjuCs" - } - ], - "services": { - "appinvite_service": { - "other_platform_oauth_client": [] - } - } - } - ], - "configuration_version": "1" -} \ No newline at end of file diff --git a/example/ios/Runner/GoogleService-Info.plist b/example/ios/Runner/GoogleService-Info.plist deleted file mode 100644 index 3d3f2510..00000000 --- a/example/ios/Runner/GoogleService-Info.plist +++ /dev/null @@ -1,32 +0,0 @@ - - - - - API_KEY - AIzaSyCbVPJwkNblldnnC6drkANOFNBR0pc16vc - GCM_SENDER_ID - 562107654987 - PLIST_VERSION - 1 - BUNDLE_ID - com.usercentrics.sdk.mediation.test - PROJECT_ID - in-app-sdk - STORAGE_BUCKET - in-app-sdk.firebasestorage.app - IS_ADS_ENABLED - - IS_ANALYTICS_ENABLED - - IS_APPINVITE_ENABLED - - IS_GCM_ENABLED - - IS_SIGNIN_ENABLED - - GOOGLE_APP_ID - 1:562107654987:ios:582fcab0c3093857befece - DATABASE_URL - https://in-app-sdk.firebaseio.com - - \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index fa4433ab..cee705ff 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -215,10 +215,10 @@ packages: dependency: transitive description: name: matcher - sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6" + sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 url: "https://pub.dev" source: hosted - version: "0.12.18" + version: "0.12.19" material_color_utilities: dependency: transitive description: @@ -380,26 +380,26 @@ packages: dependency: "direct dev" description: name: test - sha256: "54c516bbb7cee2754d327ad4fca637f78abfc3cbcc5ace83b3eda117e42cd71a" + sha256: "280d6d890011ca966ad08df7e8a4ddfab0fb3aa49f96ed6de56e3521347a9ae7" url: "https://pub.dev" source: hosted - version: "1.29.0" + version: "1.30.0" test_api: dependency: transitive description: name: test_api - sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636" + sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a" url: "https://pub.dev" source: hosted - version: "0.7.9" + version: "0.7.10" test_core: dependency: transitive description: name: test_core - sha256: "394f07d21f0f2255ec9e3989f21e54d3c7dc0e6e9dbce160e5a9c1a6be0e2943" + sha256: "0381bd1585d1a924763c308100f2138205252fb90c9d4eeaf28489ee65ccde51" url: "https://pub.dev" source: hosted - version: "0.6.15" + version: "0.6.16" typed_data: dependency: transitive description: From 281ede53d9ba8a5174fe648369a8d7104b888e35 Mon Sep 17 00:00:00 2001 From: asadraza-usercentrics Date: Fri, 8 May 2026 17:01:58 +0100 Subject: [PATCH 3/7] fix: apply dart format to example/lib/main.dart --- example/lib/main.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index dd4e81d2..c2944f10 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -10,7 +10,8 @@ import 'customization_example_2.dart'; // Build-time flag — shows the consent mediation toggle when true. // Usage: flutter run --dart-define=MEDIATION_TEST=true // Omit (or false) for normal builds — safe to publish. -const bool _kMediationTestEnabled = bool.fromEnvironment('MEDIATION_TEST', defaultValue: true); +const bool _kMediationTestEnabled = + bool.fromEnvironment('MEDIATION_TEST', defaultValue: true); // Settings ID for the sample app. When testing consent mediation this must be a // settings ID that has the target 3rd-party SDKs configured in the Usercentrics dashboard. From e273f67fa20e5e655a919af3b04598d316588b0a Mon Sep 17 00:00:00 2001 From: asadraza-usercentrics Date: Fri, 8 May 2026 17:01:58 +0100 Subject: [PATCH 4/7] fix(example): comment out Firebase plugin and local pod path to unblock CI --- example/android/app/build.gradle | 5 ++++- example/ios/Podfile | 7 ++++--- example/ios/Podfile.lock | 8 +++----- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 4a897c30..ab28d6b8 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -2,7 +2,10 @@ plugins { id "com.android.application" id "kotlin-android" id "dev.flutter.flutter-gradle-plugin" - id "com.google.gms.google-services" + // Uncomment to enable Firebase Analytics (required for consent mediation testing). + // Place google-services.json in example/android/app/ before building. + // See example/README.md for setup instructions. + // id "com.google.gms.google-services" } def localProperties = new Properties() diff --git a/example/ios/Podfile b/example/ios/Podfile index 9f119244..5350820e 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -29,10 +29,11 @@ target 'Runner' do flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) - # Local override — picks up mobile-sdk UsercentricsUI source changes without a full release - pod 'UsercentricsUI', :path => '../../../mobile-sdk/platforms/ios/UsercentricsUI' + # Uncomment to use a local UsercentricsUI build (requires mobile-sdk repo checked out + # at ../../../mobile-sdk/platforms/ios/UsercentricsUI relative to this file). + # pod 'UsercentricsUI', :path => '../../../mobile-sdk/platforms/ios/UsercentricsUI' - # Firebase — required to test MSDK-3667 (setAnalyticsCollectionEnabled via NSInvocation) + # Firebase Analytics — required for consent mediation testing. pod 'FirebaseAnalytics' target 'RunnerTests' do diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 584cb8ac..6efbbdf0 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -102,7 +102,6 @@ DEPENDENCIES: - FirebaseAnalytics - Flutter (from `Flutter`) - usercentrics_sdk (from `.symlinks/plugins/usercentrics_sdk/ios`) - - UsercentricsUI (from `../../../mobile-sdk/platforms/ios/UsercentricsUI`) - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/darwin`) SPEC REPOS: @@ -117,14 +116,13 @@ SPEC REPOS: - nanopb - PromisesObjC - Usercentrics + - UsercentricsUI EXTERNAL SOURCES: Flutter: :path: Flutter usercentrics_sdk: :path: ".symlinks/plugins/usercentrics_sdk/ios" - UsercentricsUI: - :path: "../../../mobile-sdk/platforms/ios/UsercentricsUI" webview_flutter_wkwebview: :path: ".symlinks/plugins/webview_flutter_wkwebview/darwin" @@ -141,9 +139,9 @@ SPEC CHECKSUMS: PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 Usercentrics: 26f9f31e4e83cc0de49c3913577c6a819ba172f8 usercentrics_sdk: 6be3d30f8371353fbee168b7daf8b4a92d168d84 - UsercentricsUI: 2328bf9b211e381bd312e6cd1b0951e0515cbacb + UsercentricsUI: 3ed95d8cae63a71e67c28402e8fe7367e2b14179 webview_flutter_wkwebview: 1821ceac936eba6f7984d89a9f3bcb4dea99ebb2 -PODFILE CHECKSUM: c29419e9a80f067fe8952f0a5d2bedf438aa08c8 +PODFILE CHECKSUM: e97bfdbafeca8809c8aa9477153c465633bd1c02 COCOAPODS: 1.16.2 From 83a22d7e6ff5274fd7a14074325a2a1ae07adfc4 Mon Sep 17 00:00:00 2001 From: asadraza-usercentrics Date: Mon, 11 May 2026 17:34:58 +0100 Subject: [PATCH 5/7] fix(ci): upgrade Xcode to 16.2 for Firebase 11.x Swift 6 compatibility --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 877f868b..db4a0454 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -129,7 +129,7 @@ jobs: - name: Setup code uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1 with: - xcode-version: '15.4' + xcode-version: '16.2' - name: Checkout code uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Setup Flutter @@ -199,7 +199,7 @@ jobs: - name: Setup code uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1 with: - xcode-version: '15.4' + xcode-version: '16.2' - name: Checkout code uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Setup Flutter From cab5bac98ae8c2d79275e3964d90b132d4578381 Mon Sep 17 00:00:00 2001 From: asadraza-usercentrics Date: Tue, 12 May 2026 17:27:43 +0100 Subject: [PATCH 6/7] fix(ci): use iPhone 16 simulator and stub GoogleService-Info.plist for iOS jobs --- .github/workflows/ci.yml | 44 +++++++++++++++++++++++++++++++++++++++ scripts/ios_unit_tests.sh | 2 +- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index db4a0454..a4d3db8d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -139,6 +139,28 @@ jobs: channel: 'stable' - name: Get dependencies run: flutter pub get + - name: Create stub GoogleService-Info.plist for CI + run: | + cat > example/ios/Runner/GoogleService-Info.plist << 'EOF' + + + + + API_KEYAIzaCI00000000000000000000000000000000 + GCM_SENDER_ID000000000000 + PLIST_VERSION1 + BUNDLE_IDcom.placeholder.ci + PROJECT_IDplaceholder-ci + STORAGE_BUCKETplaceholder-ci.appspot.com + IS_ADS_ENABLED + IS_ANALYTICS_ENABLED + IS_APPINVITE_ENABLED + IS_GCM_ENABLED + IS_SIGNIN_ENABLED + GOOGLE_APP_ID1:000000000000:ios:0000000000000000000000 + + + EOF - name: Setup Pods working-directory: ./example/ios run: pod install @@ -209,6 +231,28 @@ jobs: channel: 'stable' - name: Get dependencies run: flutter pub get + - name: Create stub GoogleService-Info.plist for CI + run: | + cat > example/ios/Runner/GoogleService-Info.plist << 'EOF' + + + + + API_KEYAIzaCI00000000000000000000000000000000 + GCM_SENDER_ID000000000000 + PLIST_VERSION1 + BUNDLE_IDcom.placeholder.ci + PROJECT_IDplaceholder-ci + STORAGE_BUCKETplaceholder-ci.appspot.com + IS_ADS_ENABLED + IS_ANALYTICS_ENABLED + IS_APPINVITE_ENABLED + IS_GCM_ENABLED + IS_SIGNIN_ENABLED + GOOGLE_APP_ID1:000000000000:ios:0000000000000000000000 + + + EOF - name: Build working-directory: ./example run: flutter build ios --debug --no-codesign --simulator diff --git a/scripts/ios_unit_tests.sh b/scripts/ios_unit_tests.sh index 5ef7da96..2fad2edb 100755 --- a/scripts/ios_unit_tests.sh +++ b/scripts/ios_unit_tests.sh @@ -4,6 +4,6 @@ rm -rf TestResults.xcresult xcodebuild test -workspace 'Runner.xcworkspace' \ -scheme 'Runner' \ - -destination 'platform=iOS Simulator,name=iPhone 15 Pro' \ + -destination 'platform=iOS Simulator,name=iPhone 16' \ -enableCodeCoverage YES \ -resultBundlePath TestResults From da309e6af6f5127b7c02a40d58fe5d0bd74070c0 Mon Sep 17 00:00:00 2001 From: asadraza-usercentrics Date: Tue, 12 May 2026 17:48:06 +0100 Subject: [PATCH 7/7] fix(ci): comment out FirebaseApp.configure() to prevent SIGABRT in iOS unit tests --- example/ios/Runner/AppDelegate.swift | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/example/ios/Runner/AppDelegate.swift b/example/ios/Runner/AppDelegate.swift index 7db7d3da..43280071 100644 --- a/example/ios/Runner/AppDelegate.swift +++ b/example/ios/Runner/AppDelegate.swift @@ -1,4 +1,5 @@ -import FirebaseCore +// Firebase mediation: uncomment to enable. See example/README.md for setup instructions. +// import FirebaseCore import Flutter import UIKit @@ -8,7 +9,9 @@ import UIKit _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { - FirebaseApp.configure() + // Firebase mediation: uncomment to enable. Place GoogleService-Info.plist in Runner/ first. + // See example/README.md for setup instructions. + // FirebaseApp.configure() GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) }