From 1522905ff501b69a1c705dd9ed277e83381ee52e Mon Sep 17 00:00:00 2001 From: Ben Baron Date: Fri, 3 May 2024 13:53:43 -0500 Subject: [PATCH 1/2] feat: Improve Privacy Manifest support for iOS 17 --- Package.swift | 4 +- ...icle-Google-Analytics-Firebase-GA4.podspec | 6 ++- .../project.pbxproj | 28 ++++------ .../PrivacyInfo.xcprivacy | 8 +-- .../MPKitFirebaseGA4AnalyticsTests.m | 51 +++++++------------ 5 files changed, 37 insertions(+), 60 deletions(-) diff --git a/Package.swift b/Package.swift index 98dc93c..60bf018 100644 --- a/Package.swift +++ b/Package.swift @@ -17,7 +17,7 @@ let package = Package( dependencies: [ .package(name: "mParticle-Apple-SDK", url: "https://github.com/mParticle/mparticle-apple-sdk", - .upToNextMajor(from: "8.0.0")), + .upToNextMajor(from: "8.22.0")), .package(name: "Firebase", url: "https://github.com/firebase/firebase-ios-sdk.git", .upToNextMajor(from: "10.6.0")), @@ -31,6 +31,7 @@ let package = Package( ], path: "mParticle-Google-Analytics-Firebase-GA4", exclude: ["Info.plist", "dummy.swift"], + resources: [.process("PrivacyInfo.xcprivacy")], publicHeadersPath: "."), .target( name: "mParticle-Google-Analytics-Firebase-GA4-NoLocation", @@ -40,6 +41,7 @@ let package = Package( ], path: "SPM/mParticle-Google-Analytics-Firebase-GA4-NoLocation", exclude: ["Info.plist", "dummy.swift"], + resources: [.process("PrivacyInfo.xcprivacy")], publicHeadersPath: "."), ] ) diff --git a/mParticle-Google-Analytics-Firebase-GA4.podspec b/mParticle-Google-Analytics-Firebase-GA4.podspec index 2757caa..d12184a 100755 --- a/mParticle-Google-Analytics-Firebase-GA4.podspec +++ b/mParticle-Google-Analytics-Firebase-GA4.podspec @@ -16,14 +16,16 @@ Pod::Spec.new do |s| s.ios.deployment_target = "11.0" s.ios.source_files = 'mParticle-Google-Analytics-Firebase-GA4/*.{h,m,mm}' - s.ios.dependency 'mParticle-Apple-SDK/mParticle', '~> 8.0' + s.ios.resource_bundles = { 'mParticle-Google-Analytics-Firebase-GA4-Privacy' => ['mParticle-Google-Analytics-Firebase-GA4/PrivacyInfo.xcprivacy'] } + s.ios.dependency 'mParticle-Apple-SDK/mParticle', '~> 8.22' s.ios.frameworks = 'CoreTelephony', 'SystemConfiguration' s.libraries = 'z' s.ios.dependency 'Firebase/Core', '~> 10.23' s.tvos.deployment_target = "12.0" s.tvos.source_files = 'mParticle-Google-Analytics-Firebase-GA4/*.{h,m,mm}' - s.tvos.dependency 'mParticle-Apple-SDK/mParticle', '~> 8.0' + s.ios.resource_bundles = { 'mParticle-Google-Analytics-Firebase-GA4-Privacy' => ['mParticle-Google-Analytics-Firebase-GA4/PrivacyInfo.xcprivacy'] } + s.tvos.dependency 'mParticle-Apple-SDK/mParticle', '~> 8.22' s.tvos.frameworks = 'SystemConfiguration' s.libraries = 'z' s.tvos.dependency 'Firebase/Core', '~> 10.23' diff --git a/mParticle-Google-Analytics-Firebase-GA4.xcodeproj/project.pbxproj b/mParticle-Google-Analytics-Firebase-GA4.xcodeproj/project.pbxproj index 0bacd09..91456af 100644 --- a/mParticle-Google-Analytics-Firebase-GA4.xcodeproj/project.pbxproj +++ b/mParticle-Google-Analytics-Firebase-GA4.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 60; objects = { /* Begin PBXBuildFile section */ @@ -16,8 +16,6 @@ D3C2105829FC1E3600DBB6D8 /* FirebaseAnalytics.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = D3C2104C29FC1E3400DBB6D8 /* FirebaseAnalytics.xcframework */; }; D3C2105929FC1E3600DBB6D8 /* FirebaseCoreInternal.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = D3C2104D29FC1E3400DBB6D8 /* FirebaseCoreInternal.xcframework */; }; D3C2105A29FC1E3600DBB6D8 /* FirebaseCoreInternal.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = D3C2104D29FC1E3400DBB6D8 /* FirebaseCoreInternal.xcframework */; }; - D3C2105B29FC1E3600DBB6D8 /* FirebaseAnalyticsSwift.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = D3C2104E29FC1E3400DBB6D8 /* FirebaseAnalyticsSwift.xcframework */; }; - D3C2105C29FC1E3600DBB6D8 /* FirebaseAnalyticsSwift.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = D3C2104E29FC1E3400DBB6D8 /* FirebaseAnalyticsSwift.xcframework */; }; D3C2105D29FC1E3600DBB6D8 /* FBLPromises.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = D3C2104F29FC1E3400DBB6D8 /* FBLPromises.xcframework */; }; D3C2105E29FC1E3600DBB6D8 /* FBLPromises.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = D3C2104F29FC1E3400DBB6D8 /* FBLPromises.xcframework */; }; D3C2105F29FC1E3600DBB6D8 /* FirebaseCore.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = D3C2105029FC1E3500DBB6D8 /* FirebaseCore.xcframework */; }; @@ -69,17 +67,16 @@ D316BD4D217F67BC00688E56 /* MPKitFirebaseGA4Analytics.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MPKitFirebaseGA4Analytics.m; sourceTree = ""; }; D32861EC2BA487FD0075AFF0 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; D39C3DE428C78D5B00432A0C /* dummy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dummy.swift; sourceTree = ""; }; - D3C2104C29FC1E3400DBB6D8 /* FirebaseAnalytics.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = FirebaseAnalytics.xcframework; path = Carthage/Build/FirebaseAnalytics.xcframework; sourceTree = ""; }; - D3C2104D29FC1E3400DBB6D8 /* FirebaseCoreInternal.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = FirebaseCoreInternal.xcframework; path = Carthage/Build/FirebaseCoreInternal.xcframework; sourceTree = ""; }; - D3C2104E29FC1E3400DBB6D8 /* FirebaseAnalyticsSwift.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = FirebaseAnalyticsSwift.xcframework; path = Carthage/Build/FirebaseAnalyticsSwift.xcframework; sourceTree = ""; }; - D3C2104F29FC1E3400DBB6D8 /* FBLPromises.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = FBLPromises.xcframework; path = Carthage/Build/FBLPromises.xcframework; sourceTree = ""; }; - D3C2105029FC1E3500DBB6D8 /* FirebaseCore.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = FirebaseCore.xcframework; path = Carthage/Build/FirebaseCore.xcframework; sourceTree = ""; }; - D3C2105129FC1E3500DBB6D8 /* mParticle_Apple_SDK.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = mParticle_Apple_SDK.xcframework; path = Carthage/Build/mParticle_Apple_SDK.xcframework; sourceTree = ""; }; - D3C2105229FC1E3500DBB6D8 /* FirebaseInstallations.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = FirebaseInstallations.xcframework; path = Carthage/Build/FirebaseInstallations.xcframework; sourceTree = ""; }; - D3C2105329FC1E3500DBB6D8 /* GoogleAppMeasurement.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = GoogleAppMeasurement.xcframework; path = Carthage/Build/GoogleAppMeasurement.xcframework; sourceTree = ""; }; - D3C2105429FC1E3500DBB6D8 /* GoogleUtilities.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = GoogleUtilities.xcframework; path = Carthage/Build/GoogleUtilities.xcframework; sourceTree = ""; }; - D3C2105529FC1E3500DBB6D8 /* nanopb.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = nanopb.xcframework; path = Carthage/Build/nanopb.xcframework; sourceTree = ""; }; - D3C2105629FC1E3500DBB6D8 /* GoogleAppMeasurementIdentitySupport.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = GoogleAppMeasurementIdentitySupport.xcframework; path = Carthage/Build/GoogleAppMeasurementIdentitySupport.xcframework; sourceTree = ""; }; + D3C2104C29FC1E3400DBB6D8 /* FirebaseAnalytics.xcframework */ = {isa = PBXFileReference; expectedSignature = "AppleDeveloperProgram:EQHXZ8M8AV:Google LLC"; lastKnownFileType = wrapper.xcframework; name = FirebaseAnalytics.xcframework; path = Carthage/Build/FirebaseAnalytics.xcframework; sourceTree = ""; }; + D3C2104D29FC1E3400DBB6D8 /* FirebaseCoreInternal.xcframework */ = {isa = PBXFileReference; expectedSignature = "AppleDeveloperProgram:EQHXZ8M8AV:Google LLC"; lastKnownFileType = wrapper.xcframework; name = FirebaseCoreInternal.xcframework; path = Carthage/Build/FirebaseCoreInternal.xcframework; sourceTree = ""; }; + D3C2104F29FC1E3400DBB6D8 /* FBLPromises.xcframework */ = {isa = PBXFileReference; expectedSignature = "AppleDeveloperProgram:EQHXZ8M8AV:Google LLC"; lastKnownFileType = wrapper.xcframework; name = FBLPromises.xcframework; path = Carthage/Build/FBLPromises.xcframework; sourceTree = ""; }; + D3C2105029FC1E3500DBB6D8 /* FirebaseCore.xcframework */ = {isa = PBXFileReference; expectedSignature = "AppleDeveloperProgram:EQHXZ8M8AV:Google LLC"; lastKnownFileType = wrapper.xcframework; name = FirebaseCore.xcframework; path = Carthage/Build/FirebaseCore.xcframework; sourceTree = ""; }; + D3C2105129FC1E3500DBB6D8 /* mParticle_Apple_SDK.xcframework */ = {isa = PBXFileReference; expectedSignature = "AppleDeveloperProgram:DLD43Y3TRP:mParticle, inc"; lastKnownFileType = wrapper.xcframework; name = mParticle_Apple_SDK.xcframework; path = Carthage/Build/mParticle_Apple_SDK.xcframework; sourceTree = ""; }; + D3C2105229FC1E3500DBB6D8 /* FirebaseInstallations.xcframework */ = {isa = PBXFileReference; expectedSignature = "AppleDeveloperProgram:EQHXZ8M8AV:Google LLC"; lastKnownFileType = wrapper.xcframework; name = FirebaseInstallations.xcframework; path = Carthage/Build/FirebaseInstallations.xcframework; sourceTree = ""; }; + D3C2105329FC1E3500DBB6D8 /* GoogleAppMeasurement.xcframework */ = {isa = PBXFileReference; expectedSignature = "AppleDeveloperProgram:EQHXZ8M8AV:Google LLC"; lastKnownFileType = wrapper.xcframework; name = GoogleAppMeasurement.xcframework; path = Carthage/Build/GoogleAppMeasurement.xcframework; sourceTree = ""; }; + D3C2105429FC1E3500DBB6D8 /* GoogleUtilities.xcframework */ = {isa = PBXFileReference; expectedSignature = "AppleDeveloperProgram:EQHXZ8M8AV:Google LLC"; lastKnownFileType = wrapper.xcframework; name = GoogleUtilities.xcframework; path = Carthage/Build/GoogleUtilities.xcframework; sourceTree = ""; }; + D3C2105529FC1E3500DBB6D8 /* nanopb.xcframework */ = {isa = PBXFileReference; expectedSignature = "AppleDeveloperProgram:EQHXZ8M8AV:Google LLC"; lastKnownFileType = wrapper.xcframework; name = nanopb.xcframework; path = Carthage/Build/nanopb.xcframework; sourceTree = ""; }; + D3C2105629FC1E3500DBB6D8 /* GoogleAppMeasurementIdentitySupport.xcframework */ = {isa = PBXFileReference; expectedSignature = "AppleDeveloperProgram:EQHXZ8M8AV:Google LLC"; lastKnownFileType = wrapper.xcframework; name = GoogleAppMeasurementIdentitySupport.xcframework; path = Carthage/Build/GoogleAppMeasurementIdentitySupport.xcframework; sourceTree = ""; }; D3C7855221FF6CEB00FE47D2 /* mParticle-Google-Analytics-Firebase-GA4Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "mParticle-Google-Analytics-Firebase-GA4Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; D3C7855421FF6CEC00FE47D2 /* MPKitFirebaseGA4AnalyticsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MPKitFirebaseGA4AnalyticsTests.m; sourceTree = ""; }; D3C7855621FF6CEC00FE47D2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -92,7 +89,6 @@ files = ( D3C2105D29FC1E3600DBB6D8 /* FBLPromises.xcframework in Frameworks */, D3C2106129FC1E3600DBB6D8 /* mParticle_Apple_SDK.xcframework in Frameworks */, - D3C2105B29FC1E3600DBB6D8 /* FirebaseAnalyticsSwift.xcframework in Frameworks */, D3C2106929FC1E3600DBB6D8 /* nanopb.xcframework in Frameworks */, D3C2105F29FC1E3600DBB6D8 /* FirebaseCore.xcframework in Frameworks */, D3C2106329FC1E3600DBB6D8 /* FirebaseInstallations.xcframework in Frameworks */, @@ -118,7 +114,6 @@ D3C2106829FC1E3600DBB6D8 /* GoogleUtilities.xcframework in Frameworks */, D3C2105A29FC1E3600DBB6D8 /* FirebaseCoreInternal.xcframework in Frameworks */, D3C2105E29FC1E3600DBB6D8 /* FBLPromises.xcframework in Frameworks */, - D3C2105C29FC1E3600DBB6D8 /* FirebaseAnalyticsSwift.xcframework in Frameworks */, D3C2106229FC1E3600DBB6D8 /* mParticle_Apple_SDK.xcframework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -162,7 +157,6 @@ children = ( D3C2104F29FC1E3400DBB6D8 /* FBLPromises.xcframework */, D3C2104C29FC1E3400DBB6D8 /* FirebaseAnalytics.xcframework */, - D3C2104E29FC1E3400DBB6D8 /* FirebaseAnalyticsSwift.xcframework */, D3C2105029FC1E3500DBB6D8 /* FirebaseCore.xcframework */, D3C2104D29FC1E3400DBB6D8 /* FirebaseCoreInternal.xcframework */, D3C2105229FC1E3500DBB6D8 /* FirebaseInstallations.xcframework */, diff --git a/mParticle-Google-Analytics-Firebase-GA4/PrivacyInfo.xcprivacy b/mParticle-Google-Analytics-Firebase-GA4/PrivacyInfo.xcprivacy index eb3b0ea..2009fb7 100644 --- a/mParticle-Google-Analytics-Firebase-GA4/PrivacyInfo.xcprivacy +++ b/mParticle-Google-Analytics-Firebase-GA4/PrivacyInfo.xcprivacy @@ -7,12 +7,8 @@ NSPrivacyTrackingDomains NSPrivacyCollectedDataTypes - - - + NSPrivacyAccessedAPITypes - - - + diff --git a/mParticle-Google-Analytics-Firebase-GA4Tests/MPKitFirebaseGA4AnalyticsTests.m b/mParticle-Google-Analytics-Firebase-GA4Tests/MPKitFirebaseGA4AnalyticsTests.m index 85fec49..320efc6 100644 --- a/mParticle-Google-Analytics-Firebase-GA4Tests/MPKitFirebaseGA4AnalyticsTests.m +++ b/mParticle-Google-Analytics-Firebase-GA4Tests/MPKitFirebaseGA4AnalyticsTests.m @@ -143,10 +143,10 @@ - (void)testSanitization { XCTAssertEqualObjects([exampleKit standardizeNameOrKey:badStart forEvent:YES], @"event_name"); } - NSString *tooLong = @"abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890"; + NSString *tooLong = @"abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890"; XCTAssertEqual(40, [exampleKit standardizeNameOrKey:tooLong forEvent:YES].length); XCTAssertEqual(24, [exampleKit standardizeNameOrKey:tooLong forEvent:NO].length); - XCTAssertEqual(100, [exampleKit standardizeValue:tooLong forEvent:YES].length); + XCTAssertEqual(500, [exampleKit standardizeValue:tooLong forEvent:YES].length); XCTAssertEqual(36, [exampleKit standardizeValue:tooLong forEvent:NO].length); NSArray *emptyStrings = @[@"!@#$%^&*()_+=[]{}|'\"?><:;", @@ -240,41 +240,24 @@ - (void)testSanitizationMax { XCTAssertEqual([parameters count], 25); XCTAssertEqualObjects(parameters, testFinalAttributes); - NSDictionary *testExcessiveAttributes = @{ @"test1": @"parameter", - @"test2": @"parameter", - @"test3": @"parameter", - @"test4": @"parameter", - @"test5": @"parameter", - @"test6": @"parameter", - @"test7": @"parameter", - @"test8": @"parameter", - @"test9": @"parameter", - @"test10": @"parameter", - @"test11": @"parameter", - @"test12": @"parameter", - @"test13": @"parameter", - @"test14": @"parameter", - @"test15": @"parameter", - @"test16": @"parameter", - @"test17": @"parameter", - @"test18": @"parameter", - @"test19": @"parameter", - @"test20": @"parameter", - @"test21": @"parameter", - @"test22": @"parameter", - @"test23": @"parameter", - @"test24": @"parameter", - @"z1": @"parameter", - @"z2": @"parameter", - @"z3": @"parameter", - @"z4": @"parameter", - @"z5": @"parameter" - }; + NSMutableDictionary *testExcessiveAttributes = [[NSMutableDictionary alloc] initWithCapacity:125]; + for (int i = 0; i < 125; i++) { + NSString *key = [NSString stringWithFormat:@"test%03d", i]; + testExcessiveAttributes[key] = @"parameter"; + } + + NSMutableDictionary *testExcessiveFinalAttributes = [[NSMutableDictionary alloc] initWithCapacity:125]; + for (int i = 0; i <99 ; i++) { + NSString *key = [NSString stringWithFormat:@"test%03d", i]; + testExcessiveFinalAttributes[key] = @"parameter"; + } + testExcessiveFinalAttributes[@"currency"] = @"USD"; + event.customAttributes = testExcessiveAttributes; parameters = [exampleKit getParameterForCommerceEvent:event]; - XCTAssertEqual([parameters count], 25); - XCTAssertEqualObjects(parameters, testFinalAttributes); + XCTAssertEqual([parameters count], 100); + XCTAssertEqualObjects(parameters, testExcessiveFinalAttributes); MPKitExecStatus *execStatus = [exampleKit logBaseEvent:event]; From 27b4eaec9fbb644f4c515e8b18853737bc05d02e Mon Sep 17 00:00:00 2001 From: Ben Baron Date: Fri, 3 May 2024 14:00:24 -0500 Subject: [PATCH 2/2] Update Package.swift --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 60bf018..5677b8f 100644 --- a/Package.swift +++ b/Package.swift @@ -20,7 +20,7 @@ let package = Package( .upToNextMajor(from: "8.22.0")), .package(name: "Firebase", url: "https://github.com/firebase/firebase-ios-sdk.git", - .upToNextMajor(from: "10.6.0")), + .upToNextMajor(from: "10.23.0")), ], targets: [ .target(